Ioc(控制反转) DI(依赖注入)

前端之家收集整理的这篇文章主要介绍了Ioc(控制反转) DI(依赖注入)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

IoC

IoC Inversion of Control ,控制反转, 控制权从应用程序转移到框架(如 IoC 容器),是框架共有特性
1、为什么需要IoC容器
1.1应用程序主动控制对象的实例化及依赖装配
Java代码
  1. Aa=newAImpl();
  2. Bb=newBImpl();
  3. a.setB(b);
本质:创建对象,主动实例化,直接获取依赖,主动装配
缺点:更换实现需要重新编译源代码
很难更换实现、难于测试
耦合实例生产者和实例消费者

Java代码
  1. Aa=AFactory.createA();
  2. Bb=BFactory.createB();
  3. a.setB(b);
本质:创建对象,被动实例化,间接获取依赖,主动装配 (简单工厂)
缺点:更换实现需要重新编译源代码
很难更换实现、难于测试


Java代码
  1. Aa=Factory.create(“a”);
  2. Bb=Factory.create(“b”);
  3. a.setB(b);

<!—配置.properties-->
Xml代码
  1. a=AImpl
  2. b=BImpl
本质:创建对象,被动实例化,间接获取依赖, 主动装配
(工厂 + 反射 +properties 配置文件
Service Locator 注册表)
缺点:冗余的依赖装配逻辑


我想直接:
//返回装配好的a
Java代码
  1. Aa=Factory.create(“a”);

1.2、可配置通用工厂:工厂主动控制,应用程序被动接受,控制权从应用程序转移到工
Java代码
  1. //返回装配好的a
  2. Aa=Factory.create(“a”);
<!—配置文件-->
Java代码
  1. <beanid=“a”class=“AImpl”>
  2. <propertyname=“b”ref=“b”/>
  3. </bean>
  4. <beanid=“b”class=“BImpl”/>
本质:创建对象和装配对象,
被动实例化,被动接受依赖,被动装配
(工厂 + 反射 +xml 配置文件
缺点:不通用

步骤:
1 、读取配置文件根据配置文件通过反射
创建 AImpl
2 、发现 A 需要一个类型为 B 属性 b
3 、到工厂中找名为 b 的对象,发现没有,读取
配置文件通过反射创建 BImpl
4 、将 b 对象装配到 a 对象的 b 属性
组件的配置与使用分离开(解耦、更改实现无需修改代码、易于更好实现) 】

1.3IoC(控制反转)容器:容器主动控制
Java代码
  1. //返回装配好的a
  2. Aa=ApplicationContext.getBean(“a”);
<!—配置文件-->
Java代码
  1. <beanid=“a”class=“AImpl”>
  2. <propertyname=“b”ref=“b”/>
  3. </bean>
  4. <beanid=“b”class=“BImpl”/>
本质:创建对象和装配对象、管理对象生命周期
被动实例化,被动接受依赖,被动装配
(工厂 + 反射 +xml 配置文件
通用



IoC 容器:实现了 IoC 思想的容器就是 IoC 容器

2、IoC容器特点
1 无需主动 new 对象;而是描述对象应该如何被创建即可
IoC 容器帮你创建,即被动实例化;
2 】不需要主动装配对象之间的依赖关系,而是描述需要哪个服务(组件),
IoC 容器会帮你装配(即负责将它们关联在一起),被动接受装配;
3 】主动变被动,好莱坞法则:别打电话给我们,我们会打给你;
4 】迪米特法则(最少知识原则):不知道依赖的具体实现,只知道需要提供 某类服务的对象(面向抽象编程),松散耦合,一个对象应当对其他对象有尽 可能少的了解 , 不和陌生人(实现)说话
5 IoC 是一种让服务消费者不直接依赖于服务提供者的组件设计方式, 是一种减少类与类之间依赖的设计原则

3、理解IoC容器问题关键: 控制的哪些方面被反转了?
1 、谁控制谁?为什么叫反转? ------ IoC 容器控制,而以前是应用程序控制,所以叫反转
2 、控制什么? ------ 控制应用程序所需要的资源(对象、文件 ……
3 、为什么控制? ------ 解耦组件之间的关系
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
DI :依赖注入( Dependency Injection :用一个单独的对象(装配器)来 装配对象之间的依赖关系



2、理解DI问题关键
谁依赖于谁? ------- 应用程序依赖于 IoC 容器
为什么需要依赖? ------- 应用程序依赖于 IoC 容器装配类之间的关系
依赖什么东西? ------- 依赖了 IoC 容器的装配功能
谁注入于谁? ------- IoC 容器注入应用程序
注入什么东西? ------- 注入应用程序需要的资源(类之间的关系)

更能描述容器其特点的名字 ——“依赖注入 Dependency Injection
IoC容器应该具有依赖注入功能,因此也可以叫 DI容器

3、DI优点
1 】帮你看清组件之间的依赖关系,只需要观察依赖注入的机制( setter/构造器),就可以掌握整个依赖(类与类之间的关系)。
2 】组件之间的依赖关系由容器在运行期决定,形象的来说,即由容器动态的将某种依赖关系注入到组件之中。
3 依赖注入的目标并非为软件系统带来更多的功能,而是为了提升组件重用的概率,并为系统搭建一个灵活、可扩展的平台。通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不用关心具体的资源来自何处、由谁实现。

使用 DI 限制:组件和装配器( IoC容器)之间不会有依赖关系,因此组件无法从装配器那里获得更多服务,只能获得配置信息中所提供的那些。

4、实现方式
1、构造器注入
2、 setter注入
3、接口注入:在接口中定义需要注入的信息,并通过接口完成注入
@Autowired
public void prepare(MovieCatalog movieCatalog,
CustomerPreferenceDao customerPreferenceDao) {
this.movieCatalog = movieCatalog;
this.customerPreferenceDao = customerPreferenceDao;
}



使用IoC/DI容器开发需要改变的思路
1、应用程序不主动创建对象,但要描述创建它们的方式。
2、在应用程序代码中不直接进行服务的装配,但要配置文件中描述哪一个组件需要哪一项服务。容器负责将这些装配在一起。

其原理是基于 OO设计原则的 The Hollywood PrincipleDon‘t call us,we’ll call you(别找我,我会来找你的)。也就是说,所有的组件都是被动的( Passive),所有的组件初始化和装配都由容器负责。组件处在一个容器当中,由容器负责管理。

IoC 容器功能实例化、初始化组件、装配组件依赖关系、负责组件生命周期管理。

本质:
IoC:控制权的转移,由应用程序转移到框架;
IoC/DI容器: 应用程序主动实例化对象 被动等待对象(被动实例化);
DI: 由专门的装配器装配组件之间的关系;
IoC/DI容器: 应用程序主动装配对象的依赖 应用程序被动接受依赖

猜你在找的设计模式相关文章