本文内容来自spring揭秘第四版
IoC的由来
随着轻量级容器的兴起逐渐被人们提起,全称叫
Inversion of Controller
即控制反转
何为控制反转?
用一句话概括就是:原来你要什么东西,你需要自己去取,现在是别人帮你送来
代码示例
假设我们有一个A类,需要用到B类的某个方法,没有IoC的写法是这样的
public class A {
// 用到B对象
private B b;
public A {
// 用到B就自己去new一个
b = new B();
}
public void sayHello() {
b.sayHello();
}
}
以上示例就是没有IoC的情况,我们需要什么就自己new一个对象出来
使用,这一现象的本质是我们主动去获取
,所做带来的坏处就是事必躬亲
,而且代码耦合度高
此时,我们思考一下,是否真的有必要每次都主动去获取
,我们的本质需求
是什么?
其实我们只是想要直接调用所依赖对象提供的某项服务而已,只要我用到这个对象的是时候,它可以准备就绪就行,我们不需要每次都自己new一个对象出来亦或者从何处主动获取这个对象
IoC所做的事情就是:在我们需要某个对象时,将该对象送到你这儿
,即从原来的事必躬亲到现在的享受服务,这就是所谓的反转,即让别人为你服务
,这里的别人就是IoC Service Provider
依赖注入
全称:Dependency Injenction
所谓依赖注入实际上是一种IoC的实现方式,即如果我们想要IoC Service Provider为我们提供服务,作为被注入对象,IoC是如何将我们需要依赖的对象传送过来呢?
即被注入对象是通过那些方式来告诉IoC service Provider,为其提供适当的依赖对象的呢?
具体方式分为三种:
- 构造方法注入
此形式告知IoC Service Provider通过被注入对象的构造函数
中声明的依赖对象
的参数,从而让IoC知道该被注入对象需要哪些依赖对象
IoC privider会检查被注入对象的构造函数,取得其所需要依赖的对象列表,进而为其注入相应的依赖对象
优点:通过构造方法注入的形式比较直观,且只要被注入对象一旦被构造完成,即可进入就绪状态,立马可以使用
举个恰当的例子就好比你一出生,就具备了某种超能力,就可以立即使用这种超能力了...哈哈
缺点:如果被注入对象所需要依赖的对象过多,就会导致其构造函数参数列表过长,IoC Service Provider在通过反射构造被注入对象时,其成本较高,另外是对于必须的依赖对象,可能需要引入多个重载的构造函数
此外,在java中,构造方法无法被继承,无法设置默认值
- setter方法注入
我们知道,对于JavaBean来说,通过其提供的setter方法可以用来改变对象的属性,因此被注入对象只要为其所依赖的对象对应的属性
添加相应的setter方法
,IoC Provider就可以通过这些setter方法为你注入你所需要的依赖对象
优点:随意性
强,不像构造函数那样的急性子,可以在构造完成后再注入所需要的依赖对象
且setter方法可以被继承,也允许设置默认值
缺点:当然缺点就是无法在被注入对象刚完成构造时就立马进入就绪状态
- 接口注入
第三种接口注入的形式并不像前两种一样的简单,而是必须要
实现某些接口
,才能让IoC Provider为其注入所依赖的对象
IoC Service Provider最终通过这些接口
来了解应该为被注入对象注入哪些依赖对象,类似的接口有BeanFactoryAware
, EnvirementAware
等。
实现接口的方式可能有些死板和繁琐,但从其功能上来说是可以实现注入依赖对象的功能的,只是不被推荐使用,另外其自身也处于退役状态
需要注意的是:被注入对象所实现接口中的方法名不是重要的,重要的是方法的``参数就是
被注入对象所需要注入的
依赖对象`
总结
IoC,帮助解耦各业务对象之间的依赖关系
网友评论