Contents
1) 理解容器的作用,以及容器的配置文件实现
2) 理解控制反转
a) IoC控制翻转设计原则,被用来解耦组件之间的依赖关系。
b) DI(依赖注入)是具体的设计模式,体现了IoC设计原则。DI是最典型的IoC实现。
3) 掌握依赖注入的3种实现方式,掌握各自的优缺点。
--------------------------------------华丽分割线-----------------------------
(一)容器的作用:降低组件的依赖
Problem:
面向对象设计下的系统由一组组可重用的对象组成。
每个对象自己,需要管理自己的创建和依赖。
所以这些对象之间是紧密耦合的。
Solution:
使用一个容器管理系统中需要用的所有对象的创建等生命周期动作。
运行于容器中的对象被称为组件,它们必须满足容器定义的规范。
通过容器可以减少系统中不同组件之间的耦合、依赖,提高每个组件的独立性和重用性。
本质上其实是将应用系统中与多个组件之间的依赖,转换为仅仅与管理这些组件之间的依赖。
Example:
不使用容器时业务系统中各个组件之间的依赖很复杂
使用组件管理系统中的组件后减少了部分依赖
(二)组件主动查找依赖
Problem:
通过容器管理组件,使一个系统中的组件之间的依赖仅仅是接口依赖,而不是实现依赖。
但是尽管是接口依赖,但是程序运行的时候还是有查询具体接口实现的需求的,即当组件需要外部资源(数据源、或者对其他依赖组件的引用)时。——主动查找
不同的容器对外可能提供不同的查询接口。
每个组件如果想要查询获取其依赖的接口的具体实现组件的话逻辑会很负责,且会经常变化。
所以如何提供实现简单、并且对外查询接口统一的组件查询实现呢?
Solution:
使用服务定位器来封装组件查找的复杂逻辑,同时对外提供简单的、统一的查找方法。
所有组件的查找具体依赖请求都被委派给它。
使用应用服务定位器模式可以将组件查找逻辑从组件中分离出来单独封装。
同时还可以定义统一的查找接口,可以使组件在不同的查找机制的不同环境下复用。
这是一种查找资源的通用设计模式。——JNDI????
使用服务定位器模式降低查找组件的复杂性
(三)当组件需要使用外部资源时,如何获取呢?查找——不好;要反转资源获取的方向,即IoC
组件依赖控制翻转,组件依赖注入
Problem:
主动查找,即使使用了服务定位器封装查找逻辑,仍旧有缺点:组件需要知道如何获取资源
------主动查找:
组件直接向容器、或者通过服务定位器间接向容器发起查找需要的依赖组件请求。
------IoC:
组件对外公布一种接受获取资源的方式(一般是setter方法),通过配置文件等告知容器其需要哪些资源,容器主动的将资源推送到它管理的组件中取。
Solution:
IoC:
组件对外公布一种接受获取资源的方式(一般是setter方法),通过配置文件等告知容器其需要哪些资源,容器主动的将资源推送到它管理的组件中取。
DI是IoC的最典型实现。
理解不同类型的依赖注入(DI),即不同类型的IoC实现:
1. Setter注入
2. 构造器注入
3. 接口注入
Setter注入特点(缺点):
1) 无法保证依赖一定注入了
虽然组件实例已经存在了,但是组件不能保证依赖一定已经被容器注入了;
2) 无法保证注入的依赖没有被修改
因为依赖时通过setter方法被注入的,在使用组件的业务代码中其setter方法也可以被调用,所以被注入的依赖可能被修改,这是不安全的。
构造器注入特点:
构造器注入通过构造函数保证只要组件实例初始化了,则依赖一定被注入。
缺点在于由于定义了有参数构造函数了,造成编译器不会自动生成默认构造函数,需要手工定义。
接口注入特点:
组件实现容器提供的用于注入依赖的接口。
主要的缺点在于组件高度依赖容器!所以接口注入用的很少!
(四)如何灵活实现容器管理组件、以及组件之间的依赖功能
容器作用:
容器作用管理组件生命周期
实现组件依赖管理(IoC,依赖注入)
容器能够实现系统中组件生命周期管理,以及组件间的依赖管理。
Problem:
如何通过配置文件来实现容器功能?
Solution:
即配置文件