IoC
IoC
:
Inversion of Control
,控制反转,
控制权从应用程序转移到框架(如
IoC
容器),是框架共有特性
1、为什么需要IoC容器
1.1、应用程序主动控制对象的实例化及依赖装配
- Aa=AFactory.createA();
- Bb=BFactory.createB();
- a.setB(b);
本质:创建对象,被动实例化,间接获取依赖,主动装配
(简单工厂)
缺点:更换实现需要重新编译源代码
很难更换实现、难于测试
- Aa=Factory.create(“a”);
- Bb=Factory.create(“b”);
- a.setB(b);
缺点:冗余的依赖装配逻辑
我想直接:
//返回装配好的a
- Aa=Factory.create(“a”);
1.2、可配置通用工厂:工厂主动控制,应用程序被动接受,控制权从应用程序转移到工厂
- //返回装配好的a
- Aa=Factory.create(“a”);
- <beanid=“a”class=“aimpl”>
- <propertyname=“b”ref=“b”/>
- </bean>
- <beanid=“b”class=“BImpl”/>
被动实例化,被动接受依赖,被动装配
缺点:不通用
步骤:
创建
aimpl
3
、到工厂中找名为
b
的对象,发现没有,读取
配置文件通过反射创建
BImpl
1.3、IoC(控制反转)容器:容器主动控制
- //返回装配好的a
- Aa=ApplicationContext.getBean(“a”);
- <beanid=“a”class=“aimpl”>
- <propertyname=“b”ref=“b”/>
- </bean>
- <beanid=“b”class=“BImpl”/>
本质:创建对象和装配对象、管理对象生命周期
被动实例化,被动接受依赖,被动装配
通用
IoC
容器:实现了
IoC
思想的容器就是
IoC
容器
2、IoC容器特点
【
1
】
无需主动
new
对象;而是描述对象应该如何被创建即可
IoC
容器帮你创建,即被动实例化;
IoC
容器会帮你装配(即负责将它们关联在一起),被动接受装配;
【
3
】主动变被动,好莱坞法则:别打电话给我们,我们会打给你;
【
5
】
IoC
是一种让服务消费者不直接依赖于服务提供者的组件设计方式,
是一种减少类与类之间依赖的设计原则
。
3、理解IoC容器问题关键:
控制的哪些方面被反转了?
1
、谁控制谁?为什么叫反转? ------
IoC
容器控制,而以前是应用程序控制,所以叫反转
4
、控制的哪些方面被反转了? ------
程序的控制权发生了反转:从应用程序转移到了IoC
容器。
思考:
1: IoC/DI等同于工厂吗?
2: IoC/DI跟以前的方式有什么不一样?
领会:
主从换位的思想
4、实现了IoC思想的容器就是轻量级容器吗?
如果仅仅因为使用了控制反转就认为这些轻量级容器与众不同,
就好象在说我的轿车与众不同因为它有四个轮子?
容器:提供组件运行环境,管理组件声明周期(不管组件如何创建的以及组件之间关系如何装配的);
IoC容器不仅仅具有容器的功能,而且还具有一些其他特性---如依赖装配
控制反转概念太广泛,让人迷惑,后来
Martin
Fowler
提出依赖注入概念
Martin
Fowler
Inversion of Control Containers and the Dependency Injection pattern
http://martinfowler.com/articles/injection.html
DI
2、什么是DI
2、理解DI问题关键
谁依赖于谁? -------
应用程序依赖于
IoC
容器
为什么需要依赖? -------
应用程序依赖于
IoC
容器装配类之间的关系
依赖什么东西? -------
依赖了
IoC
容器的装配功能
谁注入于谁? -------
IoC
容器注入应用程序
注入什么东西? -------
注入应用程序需要的资源(类之间的关系)
更能描述容器其特点的名字
——“依赖注入
”(
Dependency Injection)
3、DI优点
使用
DI
限制:组件和装配器(
IoC容器)之间不会有依赖关系,因此组件无法从装配器那里获得更多服务,只能获得配置信息中所提供的那些。
4、实现方式
1、构造器注入
2、
setter注入
3、接口注入:在接口中定义需要注入的信息,并通过接口完成注入
@Autowired
public void prepare(MovieCatalog movieCatalog,
CustomerPreferenceDao customerPreferenceDao) {
this.movieCatalog = movieCatalog;
this.customerPreferenceDao = customerPreferenceDao;
}
使用IoC/DI容器开发需要改变的思路
1、应用程序不主动创建对象,但要描述创建它们的方式。
其原理是基于
OO设计原则的
The Hollywood Principle:
Don‘t call us,we’ll call you(别找我,我会来找你的)。也就是说,所有的组件都是被动的(
Passive),所有的组件初始化和装配都由容器负责。组件处在一个容器当中,由容器负责管理。
IoC
容器功能:实例化、初始化组件、装配组件依赖关系、负责组件生命周期管理。
本质:
IoC:控制权的转移,由应用程序转移到框架;
IoC/DI容器:
由应用程序主动实例化对象
变被动等待对象(被动实例化);
DI: 由专门的装配器装配组件之间的关系;
IoC/DI容器:
由应用程序主动装配对象的依赖
变应用程序被动接受依赖