2.Spring之相关概念

控制反转IoC

Spring的核心概念是IoC,抽象概念是依赖关系的转移,控制反转意思就是说,当我们调用一个方法或者类时,不再由我们主动去创建这个类的对象,控制权交给别人(spring)。从对象的角度来说,可以避免对象之间的耦合,从容器的角度来说,可以避免应用程序因依赖于容器的功能,而从容器脱离。简单地说,在进行模块设计时,高层的抽象模块通常是与业务逻辑相关的模块,它应该具有重用性,而不依赖于低层的实现模块,如果高层模块直接调用低层模块的函数,就对低层模块产生了依赖关系。IoC模式基本上是一个高层的模式概念,实现IoC有两种方式:Dependency injection与Service Locator,Spring采用的是Dependency injection来实现,翻译即依赖注入。

依赖注入DI

 依赖注入的意义是:保留抽象接口,让组件依赖于抽象接口,当组件要与其他实际的对象发生依赖关系时,由抽象接口来注入依赖的实际对象。若以对象导向的方式来设计,依赖注入解释为“程序不应依赖于实现,而是依赖于抽象接口”。依赖注入有三种基本实现方式:Interface injection、Setter injection与Construction injection,分别称为接口注入、setter方法注入与构造方法注入。

IoC和DI由什么关系呢?其实它们是同一个概念的不同角度描述,由于控制反转概念比较含糊(可能只是理解为容器控制对象这一个层面,很难让人想到谁来维护对象关系),所以2004年大师级人物Martin?Fowler又给出了一个新的名字:“依赖注入”,相对IoC?而言,“依赖注入”明确描述了“被注入对象依赖IoC容器配置依赖对象”。

1.接口注入

使用接口注入会要求实现接口,对象所在的容器也会使用这个接口,容器知道接口上所规定的方法,所以可以调用实现接口的对象来完成依赖关系的注入,例如

public class ClassA {  
  private InterfaceB clzB;  
  public void doSomething() {  
    Ojbect obj = Class.forName(Config.ImplementationB).newInstance();  
    clzB = (InterfaceB)obj;  
    clzB.doIt();   
  }  
……  
}  

ClassA依赖于InterfaceB的实现,我们如何获得InterfaceB的实现实例呢?传统的方法是在代码中创建 InterfaceB实现类的实例,并将赋予clzB.这样一来,ClassA在编译期即依赖于InterfaceB的实现。为了将调用者与实现者在编译期分离,于是有了上面的代码。我们根据预先在配置文件中设定的实现类的类名(Config.ImplementationB)动态加载实现类,并通过InterfaceB强制转型后为ClassA所用,这就是接口注入的一个最原始的雏形。

2.setter方法注入

即当前对象只需要为其依赖对象添加setter方法,IOC容器通过此setter方法将相应的依赖对象设置到被注入对象的方式即setter方法注入。

public class Business {
    private IDeviceWriter writer;
    public void setWriter(IDeviceWriter writer) {
        this.writer = writer;
    }
    public void save() {
        writer.saveToDevice();
    }
}

3.构造方法注入

即被注入对象可以通过在其构造方法中声明依赖对象的参数列表,让外部(通常是IOC容器)知道它需要哪些依赖对象,然后IOC容器会检查被注入对象的构造方法, 取得其所需要的依赖对象列表,进而为其注入相应对象。使用构造方法注入的好处是可以在构造对象的同时建立依赖关系,然而如果建立的对象关系很多,这时候使用Setter来注入依赖关系更合理。

public class Business {
    private IDeviceWriter writer;
    public Business(IDeviceWriter writer) {
        this.writer = writer;
    }
    public void save() {
        writer.saveToDevice();
    }
}

接口注入 && setter注入 && 构造器注入

接口注入:接口注入模式因为具备侵入性,它要求组件必须与特定的接口相关联,因此并不被看好,实际使用有限。

Setter 注入:对于习惯了传统 javabean 开发的程序员,通过 setter 方法设定依赖关系更加直观。如果依赖关系较为复杂,那么构造子注入模式的构造函数也会相当庞大,而此时设值注入模式则更为简洁。如果用到了第三方类库,可能要求我们的组件提供一个默认的构造函数,此时构造子注入模式也不适用。

构造器注入:在构造期间完成一个完整的、合法的对象。所有依赖关系在构造函数中集中呈现。依赖关系在构造时由容器一次性设定,组件被创建之后一直处于相对“不变”的稳定状态。只有组件的创建者关心其内部依赖关系,对调用者而言,该依赖关系处于“黑盒”之中。

IoC和DI有什么关系呢?

要理解IOC和DI的关系,就要理解这两个概念,理解Ioc的关键是要明确“谁控制谁,控制什么,为何是反转(有反转就应该有正转了),哪些方面反转了”。理解DI的关键是:“谁依赖谁,为什么需要依赖,谁注入谁,注入了什么”。

1.谁控制谁,控制什么

传统Java SE程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象;而IoC是有专门一个容器来创建这些对象,即由Ioc容器来控制对象的创建;谁控制谁?当然是IoC 容器控制了对象;控制什么?那就是主要控制了外部资源获取(不只是对象包括比如文件等)。

2.为何是反转,哪些方面反转了

有反转就有正转,传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转;而反转则是由容器来帮忙创建及注入依赖对象,对象只是被动的接受依赖对象;哪些方面反转了?依赖对象的获取被反转了

3.谁依赖于谁

当然是应用程序依赖于IoC容器

4.为什么需要依赖

应用程序需要IoC容器来提供对象需要的外部资源

5.谁注入谁

很明显是IoC容器注入应用程序某个对象,应用程序依赖的对象

6.注入了什么

就是注入某个对象所需要的外部资源(包括对象、资源、常量数据)

 

IoC和DI有什么关系呢?其实它们是同一个概念的不同角度描述,由于控制反转概念比较含糊(可能只是理解为容器控制对象这一个层面,很难让人想到谁来维护对象关系),所以2004年大师级人物Martin Fowler又给出了一个新的名字:“依赖注入”,相对IoC而言,“依赖注入”明确描述了“被注入对象依赖IoC容器配置依赖对象”。依赖注入是从应用程序的角度在描述,可以把依赖注入描述的完整点:应用程序依赖容器创建并注入它所需要的外部资源;而控制反转是从容器的角度在描述,描述的完整点:容器控制应用程序,由容器反向的向应用程序注入应用程序所需要的外部资源。最直接了当的就是控制翻转是通过依赖注入实现的。

总结

IoC不是一种技术,只是一种思想,一个重要的面向对象编程的法则,它能指导我们如何设计出松耦合、更优良的程序。传统应用程序都是由我们在类内部主动创建依赖对象,从而导致类与类之间高耦合,难于测试;有了IoC容器后,把创建和查找依赖对象的控制权交给了容器,由容器进行注入组合对象,所以对象与对象之间是松散耦合,这样也方便测试,利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活。

其实IoC/DI对编程带来的最大改变不是从代码上,而是从思想上,发生了“主从换位”的变化。应用程序原本是老大,要获取什么资源都是主动出击,但是在IoC/DI思想中,应用程序就变成被动的了,被动的等待IoC/DI容器来创建并注入它所需要的资源了。

这么小小的一个改变其实是编程思想的一个大进步,这样就有效的分离了对象和它所需要的外部资源,使得它们松散耦合,有利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活。

 

参考:

https://www.cnblogs.com/xing901022/p/3963962.html

http://www.cnblogs.com/xing901022/p/4178963.html

http://www.cnblogs.com/xing901022/category/642864.html

http://blog.csdn.net/iycynna_123/article/details/52414104

http://blog.csdn.net/u011637069/article/details/51958918

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值