`
gaoyuntao2005
  • 浏览: 303066 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

入门 03 - 依赖注入DI

阅读更多


 IoC模式基本上是一个高层的概念,在Martin Fowler的Inversion of Control Containers and the Dependency Injection pattern中谈到,实现IoC有两种方式:Dependency Injection与Service Locator。您可以在下面的网址中找到该篇文章:
http://www.martinfowler.com/articles/injection.html 
 Spring所采用的是Dependency Injection来实现IoC,中文翻译为依赖注入,依赖注入的意义是:「保留抽象接口,让组件依赖于抽象接口,当组件要与其它实际的对象发生依赖关系时,藉过抽象接口来注入依赖的实际对象。」
 看看下面这个程序:

public class BusinessObject {

    private FloppyWriter writer = new FloppyWriter();

    ....

  

    public void save() {

        ...

        writer.saveToFloppy();

 

    }

}


 BusinessObject依赖于实际的FloppyWriter,为了让BusinessObject获得重用性,我们不让BusinessObject依赖于实际的FloppyWriter,而是依赖于抽象的接口:

public interface IDeviceWriter {

    public void saveToDevice();

}

 

public class BusinessObject {

    private IDeviceWriter writer;

 

    public void setDeviceWriter(IDeviceWriter writer) {

        this.writer = writer;

    }

 

    public void save() {

        ....

        writer.saveToDevice();

    }

}

 

public class FloppyWriter implement IDeviceWriter {

    public void saveToDevice() {

        ....

        // 实际储存至Floppy的程序代码

    }

}

 

public class UsbDiskWriter implement IDeviceWriter {

    public void saveToDevice() {

        ....

        // 实际储存至UsbDisk的程序代码

    }

}


 如果今天BusinessObject想要与UseDiskWriter对象发生依赖关系,可以这么建立:

businessObject.setDeviceWriter(new UsbDiskWriter());


 由于BusinessObject依赖于抽象接口,在需要建立依赖关系时,我们可以透过抽象接口注入依赖的实际对象。
 依赖注入在Martin Fowler的文章中谈到了三种实现方式:interface injection、setter injection与constructor injection。并分别称其为type 1 IoC、type 2 IoC与type 3 IoC。
 上面的BusinessObject所实现的是type 2 IoC,透过setter注入依赖关系,而type 3 IoC,则在是建构函式上注入依赖关系,例如:

public class BusinessObject {

    private IDeviceWriter writer;

 

    public BusinessObject(IDeviceWriter writer) {

        this.writer = writer;

    }

 

    public void save() {

        ....

        writer.saveToDevice();

    }

}


 Spring鼓励的是setter injection,但也允许您使用constructor injection,使用setter或constructor来注入依赖关系视您的需求而定,使用constructor的好处之一是,您可以在建构物件的同时一并完成依赖关系的建立,然而如果要建立的对象关系很多,则会在建构函式上留下一长串的参数,这时使用setter会是个不错的选择,另一方面, setter可以有明确的名称可以了解注入的对象会是什么,像是setXXX()这样的名称会比记忆constructor上某个参数位置代表某个对象来得好。
 Type 1 IoC是interface injection,使用type 1 IoC时会要求实作接口,这个接口是为容器所用的,容器知道接口上所规定的方法,它可以呼叫实作接口的对象来完成依赖关系的注入,例如:

public interface IDependencyInjection {

    public void createDependency(Map dependObjects);

}

 

public class BusinessObject implement IDependencyInjection {

    private Map dependObjects;

 

    public void createDependency(Map dependObjects) {

        this.dependObject = dependObjects;

        // 在这边实现与BusinessObject的依赖关系

        ......

    }

 

    public void save() {

        ....

        writer.saveToDevice();

    }

}


 如果要完成依赖关系注入的对象,必须实现IDependencyInjection接口,并交由容器管理,容器会呼叫被管理对象的createDependency()方法来完成依赖关系的建立。
 在上面的例子中,type 1 IoC要求BusinessObject实现特定的接口,这就使得BusinessObject依赖于容器,如果日后BusinessObject要脱离目前这个容器,就必须修改程序,想想在更复杂的依赖关系中产生更多复杂的接口,组件与容器(框架)的依赖会更加复杂,最后使得组件无法从容器中脱离。
 所以type 1 IoC具有强的侵入性,使用它来实现依赖注入会使得组件相依于容器(框架),降低组件的重用性。

 Spring的核心是个IoC容器,您可以用setter或constructor的方式来实现您的业务对象,至于对象与对象之间的关系建立,则透过组态设定,让Spring在执行时期根据组态档的设定来为您建立对象之间的依赖关系,您不必特地撰写一些Helper来自行建立这些对象之间的依赖关系,这 不仅减少了大量的程序撰写,也降低了对象之间的耦合程度。

分享到:
评论

相关推荐

    JavaEE spring 依赖注入DI入门案例

    JavaEE spring 依赖注入DI入门案例

    Spring框架控制反转IOC和依赖注入DI详解

    本文介绍了Spring框架中的控制反转IOC和依赖注入DI,欢迎阅读,共同学习,一起进步。 Spring框架基础参考:深入学习Spring基础 文章目录一.入门程序和IOC简介二.IOC-控制反转三.DI-依赖注入四. IOC和DI五.Spring...

    Spring从入门到入土——依赖注入(DI)

    DIDependency Injection概念注入方式...Spring从入门到入土——依赖注入(DI) Spring从入门到入土——Bean的作用域 Dependency Injection 概念 依赖注入(DI) 依赖:指Bean对象的创建依赖于容器。Bean对象的依赖资

    基于框架的Web开发-IoC(控制反转)和DI(依赖注入)入门.doc

    1.2 IoC(控制反转)和DI(依赖注入)入门 1 传统的Java类 在工程下创建包ioc,在ioc包中创建类Test。(为了看起来清楚,将三个类写在了同一个Java文件中,其中唯一的public类为Test)。类的含义和关系如下: Car类...

    Spring_01_入门篇_依赖注入(控制反转)_XML

    此文档仅供初学者学习,包括Spring的依赖注入(控制反转)的详细实例。以三层贯穿实例(持久层、业务层、控制层),由MAIN方法直接调用测试用例。

    bali-di-scala:Bali DI for Scala是用于依赖项注入的代码生成器

    巴厘岛DI为Scala Bali Scala的DI是一个纯def宏,它可以将抽象语法树转换为自动依赖项注入。 目前,它支持Scala 2.13,并在路线图中提供了Scala 3。 该项目是Scala中的的重新实现。 作为重新实现,它基于完全相同的...

    fastify-awilix:依赖注入支持进行固定

    固定附件 使用对Fastify框架进行依赖注入支持入门首先安装软件包和awilix: npm i fastify-awilix awilix 接下来,设置插件: const { fastifyAwilixPlugin } = require ( 'fastify-awilix' )const fastify = ...

    Ray.Di:适用于PHP的Guice样式依赖项注入框架

    概述Ray.Di软件包为依赖项注入器提供了以下功能: 构造器注入和二传手注入自动注射构造后初始化原始PHP工厂代码编译器绑定注释/属性使用注入点元数据进行上下文注入面向方面的编程(AOP) 辅助注射空对象入门创建...

    di6:ES6类的依赖注入

    入门 class Car { /** * Creates instance of Car, * expects 1 parameter object argument with dependencies * * @param { object } dependencies * @param { Engine } dependencies.engine */ ...

    用于TypeScript的简单DI库-JavaScript开发

    安装纱线添加typesafe-di入门设计您的脚踏车类型HasName = {名称:str typesafe-di零依赖简单DI库,用于以类型安全的方式创建DI容器。 安装yarn add typesafe-di入门设计您的虚拟类型HasName = {name:string}; 输入...

    AngularJS入门教程之XHR和依赖注入详解

    我们将使用AngularJS的依赖注入(dependency injection (DI))功能来为PhoneListCtrl控制器提供这个AngularJS服务。 请重置工作目录: git checkout -f step-5 刷新浏览器,你现在应该能看到一个20部手机的列表。 ...

    台风:Objective-C强大的依赖注入:sparkles::sparkles:(https:PILGRIM.PH是台风的纯粹Swift继承者!):sparkles::sparkles:

    Cocoa和CocoaTouch的强大依赖注入。 重量轻,但功能齐全,而且超级易于使用。 是台风的纯粹斯威夫特继任者!! 台风使用Objective-C运行时来收集元数据并实例化对象。 它为成千上万的Objective-C应用程序提供了动力...

    dinode:Node.js的依赖注入框架(通常是JavaScript)

    双节点Node.js的依赖注入框架(通常是JavaScript)入门这里显示了非常基本的内容。 首先,创建注射器的实例。 然后根据常量模块创建形状模块。 然后创建一个没有依赖性的常量模块。 最后是一个匿名模块,具体取决于...

    hiboot:hiboot是具有依赖项注入支持的高性能Web和cli应用程序框架

    它借用了一些Spring功能,例如依赖项注入,面向方面的编程和自动配置。 您可以通过具有依赖项注入支持的自动配置轻松集成任何其他库。 如果您是Java开发人员,则可以开始学习Go编码而无需学习任何技巧。 总览 Web ...

    Spring IOC的快速入门案例

    Spring IOC的快速入门案例 >下载Spring的开发包 ...>理解IOC控制反转和DI依赖注入 >编写Spring核心配置文件 >在程序中读取Spring配置文件,通过Spring框架获得Bean,完成相应操作 Spring 4.x的目录结构  

    spring入门上手小例子

    spring入门上手小例子,包括最基本最简单的的依赖注入和aop编程例子。

    sdp-sp3-2021-回购代码

    DI-类中的依赖项注入示例,包括HelloWorld示例集 第三周的例子 第二周的例子 common.widget-JPMS示例的一部分 并发 corejava-Cay Horstmann的书中的示例代码 匕首-DI框架示例 默认设置- default的界面 design...

    JSF2.0快速入门的基本教程.ppt

    整个过程是通过“依赖注入(DI)”来实现的,看来这是目前解偶合的最佳途径啊,spring的影响真是深远。不过正式因为jsf采用了这样的方式,导致开发工作和以前的jsp/struts等都有非常大的不同,需要一定的时间去学习。...

    typedi:用于JavaScript和TypeScript的简单但功能强大的依赖项注入工具

    主要功能包括: 基于属性的注入基于构造函数的注入单例和临时服务支持多个DI容器安装注意:本安装指南适用于TypeScript,如果您希望使用不带Typescript的TypeDI,请阅读有关入门的文档。 要开始使用TypeDI,请通过...

    Spring从入门到入土——Bean的作用域

    Spring从入门到入土——依赖注入(DI) Spring从入门到入土——Bean的作用域 Bean的作用域 ​ 在Spring中,那些组成应用程序的主体及由Spring IoC容器所管理的对象,被称之为bean。简单地讲,bean就是由IoC容器初始...

Global site tag (gtag.js) - Google Analytics