目录
前言
本篇简单介绍了IOC的概念、注入方式以及配置方式,部分内容总结摘抄自《spring揭秘》,仅作笔记。
一、IoC是什么?
IoC的全称是Inversion of Control,翻译过来就是控制反转的意思。以前我们的编码习惯是需要什么对象的时候直接new一个出来就好了,然而有个人突然出来跟我们说以后不需要我们主动去new对象了,我们需要什么对象跟它说它就会为我们准备好,这我们当然是乐意的,这个人就是IoC。控制反转的意思就是我们将对象的创建和管理权交给IoC Service Provider(IoC思想的具体实现)。
使用IoC之前的我们就好比一个大龄青年,想要什么对象都需要自己去找,IoC Service Provider就好比是婚介所,我们只要将我们需要对象的条件告诉它,它就能帮我们在已经在婚介所登记的符合我们条件的对象找出来。在这个例子中可以看出,我们并不是什么都不做,想要什么对象IoC Service Provider就会给我们。首先我们需要先将对象在IoC Service Provider登记,然后在需要某个对象时告诉它我们需要的对象的特征。
二、注入方式
我们首先来介绍我们告诉婚介所(IoC Service Provider)所需要的对象特征的做法,在IoC中也被称为DI(Dependency Injection,依赖注入)。依赖注入的方式有三种,分别是构造方法注入、setter方法注入和接口注入,由于接口注入不常用,因此我们只介绍构造方法注入和setter方法注入。
1.构造方法注入
构造方法注入就是通过在构造函数中声明依赖对象的参数列表的方式来告知IoC Service Provider。例如对于一个车对象来说,必须依赖燃料对象才能跑起来。IoC Service Provider会检查被注入对象的构造方法,取得它所需要的依赖对象列表,进而为其注入相应的对象。
public class Car {
/**
* 燃料
*/
private Fuel fuel;
public Car(Fuel fuel) {
this.fuel = fuel;
}
}
这种方法的优势是,对象在构造完成后就已经进入就绪状态,可以马上使用。但当该对象依赖的对象比较多的时候,构造方法的参数列表就会过长,并且构造方法无法被继承,无法设置默认值。
2.setter方法注入
setter方法就是javaBean中的set()方法,因此setter方法注入就是通过set()方法来为依赖的对象赋值。
public class Car {
/**
* 燃料
*/
private Fuel fuel;
public Fuel getFuel() {
return fuel;
}
public void setFuel(Fuel fuel) {
this.fuel = fuel;
}
}
setter方法注入相比较构造方法注入,可以被继承和设置默认值,缺点就是无法在构造完成后立刻进入就绪状态。
三、IoC Service Provider
上面介绍的依赖注入只是让我们声明了我们需要的依赖,最终仍然需要一个角色将可能拥有庞大且复杂依赖关系的对象们绑定到一起,IoC Service Provider就是IoC中这样的一个角色。在婚介所例子中,依赖注入只是让我们声明了我们要寻找的对象的条件,仍然需要一个婚介所(IoC Service Provider)来提供我们想要的对象以及管理在婚介所注册的其他对象。
IoC Service Provider主要有两个职责:业务对象的构建管理和业务对象间的依赖绑定。
- 业务对象的构建管理。在IoC思想下,我们无需主动去创建和管理依赖对象,但这部分工作总是需要人来做的,IoC Service Provider将对象的构建和管理逻辑从我们手里接了过去。
- 业务对象间的依赖绑定。除了业务对象的构建和管理工作,识别对象间的依赖关系并且正确的依赖注入也是IoC Service Provider需要做的,否则无法保证在某个业务对象被使用时是就绪状态的。
IoC Service Provider毕竟不是人,不能自动辨别我们需要哪些业务对象,这就需要我们告诉它对象之间的依赖关系以方便管理。”告诉“的方式有很多种,取决于具体的IoC Service Provider的实现。最常用的注册对象管理信息的方式主要有:直接编码方式、配置文件方式和元数据方式。我们最常见的还是配置文件的方式,其中配置文件的格式又包括普通文件文件、properties文件和XML文件,其中最常用的是XML文件的方式。Spring的IoC容器使用的都是XML配置文件的方式,后面介绍时会详细介绍,此处不再赘述。
总结
从主动获取依赖关系的方式转向IoC的方式,不仅仅是一种方向上的改变,IoC模式还带来了很多便利,例如以上介绍的这些不会对业务对象构成较强的侵入性、使用IoC方式的对象具有更好的可测试性、可重用性和可扩展性等等。