控制反转(IOC):
由框架或其他某些东西来控制需要调用的事件处理器或其他东西,而不是由业务逻辑决定。
举例:spring中的bean,我们在spring项目中配置了datasource后,不需要关注如何调用它,调用它这个工作交给spring,我们只需要关注我们的真正业务。
这样主控被反转了。控制权从业务逻辑中转移到其他地方。数据库操作典型的例子:打开和关闭连接。
IoC的不同实现:1.工厂模式 2.服务定位器模式 3.依赖注入(DI)
IoC会确保一个可重用的依赖项会被配置成单例。
依赖注入(DI):
依赖注入是IoC的一种特定形态,是指寻找依赖项的过程不在当前执行代码的直接控制之下。当然我们也可以自己写代码实现依赖注入。
注:把依赖项注入对象的方法有很多种,可以使用专门的DI框架,也可以显示的创建对象实例(依赖项)并把它们传入对象中也可以和框架注入达到同样效果。
DI的几个明显特点:松耦合,易测性,内聚性(专注业务),可重用,代码更少。
发展:
JAVA DI标准化方式JSR-330进行统一的规范依赖注入,2009年 JSR-299在300基础上规范企业应用提供标准化配置。实现是 javax.inject。
了解依赖注入机制的内部工作原理可以解决很多常见的问题:
1.依赖项配置错误,2.依赖项诡异的超出作用域,3.依赖项在不该共享时被共享以及分布调试离奇跌机。
javax.inject包含一个 Provider<T> 接口 和 5个注解类型 @Inject @Qualifier @Named @Scope @Singleton
详解:
@Inject 范围: 1.构造器,2.方法 ,3.属性
在构造器上使用时,构造器的参数会在运行时有配置好的IoC容器提供。在不含参数的构造器上使用Inject也合法。
注:JRE无法决定构造器注入的优先级,所以规范中规定类中只能有一个构造器带@Inject注解。
在方法上使用时,不能声明方法为抽象的。也不能声明其自身的类型参数。
@ Qualifier
用于区别两个相同类型的对象。JSR330要求所有IOC容器都必须提供一个默认的@Qualifier注解。@Named--用来给两个相同类型的对象设置不同的别名
@Scope
用于定义注入器(IOC容器)对注入对象的重用方式。
如果没有声明该注解,IOC应该创建注入对象并且仅使用该对象一次。
@ Singleton
在需要注入一个不会改变的对象时就要用 @ Singleton
Provider<T>
如果要对由DI框架注入代码中的对象有更多控制权,可以要求DI框架将Provider<T>接口实现注入对象。这样,
1.可以获取该对象的多个实例
2.可以延迟获取该对象
3.可以打破循环依赖
4.可以定义作用域
该接口仅有一个T get()方法,返回一个注入好的注入对象T。
Class Mur{
@Inject
Mur (Provider<Message> messageProvider){
Message m1=messageProvider.get();
if(someGlobalCondition){
Message copyMsg1=messageProvider.get();
}
.....
}
}
来源:oschina
链接:https://my.oschina.net/u/1024107/blog/751694