Spring IOC DI依赖注入 IOC容器 Spring Bean的声明周期
Spring IOC
- 了解Spring IOC
- 什么DI 依赖注入,为什么要用依赖注入
- 若要满足上面的需求,最早的做法,
- 使用DI示例
- 控制反转IOC
- IOC DI DL的关系
- 依赖倒置原则、 IOC、 DI、 IOC容器
- 控制反转容器做了什么事情
- Spring IOC支持的功能
- Spring IOC容器的核心接口
- Spring bean 的作用
- Spring Bean的声明周期
- 创建
- 销毁
了解Spring IOC
IOC(Inversion Of Control):控制反转。spring core 最核心的部分之一,可以说没有IOC spring就不会这么火。
想要理解IOC,需要先明白DI(Dependency Inversion)依赖注入。
什么DI 依赖注入,为什么要用依赖注入
通过模拟造汽车举例说明,DI具体做的了什么事情。
假设造一辆汽车Car,需要依赖汽车三大件:发动机 engine,底盘 underpan,变速箱 gearbox, 这三大件有依赖很多零件,用 Screw (螺丝)表示。
若要满足上面的需求,最早的做法,
假设零件的尺寸决定最终造出来什么的汽车。我们在造汽车的时候定义好零件的尺寸我10.
整个依赖关系就是:汽车–依赖–>三大件,三大件–依赖–>零件。
上层依赖于下层,如果我么需要修改下层的构造函数,如修改Screw 的构造函数,就需要修改上层所有类的构造函数。牵一发而动全身。
/** * @author lingyiwin * 造一辆汽车 */
public class Test {
public static void main(String[] args) {
Car car = new Car(10);
car.move();
}
}
/** * 假设造一辆汽车需要依赖 发动机,变速箱,底盘 */
public class Car {
private Engine engine;
private Gearbox gearbox;
private Underpan underpan;
public Car(int size) {
this.engine = new Engine(size);
this.gearbox = new Gearbox(size);
this.underpan = new Underpan(size);
}
public void move(){
//逻辑体
}
}
public class Engine {
private Screw screw;
public Engine(int size) {
this.screw = new Screw(size);
}
}
public class Gearbox {
private Screw screw;
public Gearbox(int size) {
this.screw = new Screw(size);
}
}
public class Underpan {
private Screw screw;
public Underpan(int size) {
this.screw = new Screw(size);
}
}
/** * 螺丝,假设螺丝就是汽车三大件的必须依赖的散件 */
public class Screw {
int size;
public Screw(int size) {
this.size = size;
}
}
使用DI示例
将整个依赖关系修改一下为:汽车–注入–>三大件,三大件–注入–>零件。
此时,如果需要改动零件的构造方法,将不需要修改上层的构造方法。
这样编程,更利于协同开发,单元测试。
public class Test {
public static void main(String[] args) {
Screw screw = new Screw(10);
Engine engine = new Engine(screw);
Gearbox gearbox = new Gearbox(screw);
Underpan underpan = new Underpan(screw);
Car car = new Car(engine, gearbox, underpan);
car.move();
}
}
public class Car {
private Engine engine;
private Gearbox gearbox;
private Underpan underpan;
public Car(Engine engine, Gearbox gearbox, Underpan underpan) {
this.engine = engine;
this.gearbox = gearbox;
this.underpan = underpan;
}
public void move(){
//逻辑体
}
}
public class Engine {
private Screw screw;
public Engine(Screw screw) {
this.screw = screw;
}
}
public class Gearbox {
private Screw screw;
public Gearbox(Screw screw) {
this.screw = screw;
}
}
public class Underpan {
private Screw screw;
public Underpan(Screw screw) {
this.screw = screw;
}
}
public class Screw {
int size;
public Screw(int size) {
this.size = size;
}
}
控制反转IOC
需要上层控制下层,而不是下层控制 。使用DI依赖注入来实现控制反转IOC。
所谓的DI依赖注入:把底层类对象作为上层类的参数传递给上层类,实现上层对下层的“控制”。
IOC DI DL的关系
DI(依赖注入)和DL(依赖查找)是IOC(控制反转)的两种形式。
DL(Dependency Lookup):依赖查找。相对DI更为主动一些
- 使用框架提供的方法获取对象,获取时需要提供相关配置文件路径的信息来确定获取文件的状态。
- ==DL已经被抛弃。==因为它需要用户自己使用API查找资源和组装对象,具有侵入性。
DI(Dependency Injection)当今主流实现。
- set注入:setter Injection
- 接口注入:Interface Injection
- 注释注入:Annotation Injection
- 构造器注入:Constructor Injection
依赖倒置原则、 IOC、 DI、 IOC容器
依赖倒置原则:高层模块不应该依赖底层模块,都应该依赖其抽象。
因倒置原则的思路,有了IOC控制反转。
实现IOC控制反转的方法,就是我们所说的DI。
spring框架基于IOC提出IOC容器的概念。
- 管理bean的生命周期.
- 控制bean的依赖注入.
控制反转容器做了什么事情
IOC容器:
- 避免在到处使用new来创建类,且可以做到统一维护。
- 创建实例的过程中,不需要了解容器实现的细节。
控制反转容器实现的细节就是如下代码块:
Screw screw = new Screw(10);
Engine engine = new Engine(screw);
Gearbox gearbox = new Gearbox(screw);
Underpan underpan = new Underpan(screw);
Car car = new Car(engine, gearbox, underpan);
Spring IOC容器:利用Java语言的反射功能实例化Bean,并建立Bean之间的依赖关系。
Spring IOC支持的功能
- 依赖注入
- 依赖检查
- 自动装配
- 支持集合
- 指定初始化方法和销毁方法
- 支持回调方法
Spring IOC容器的核心接口
- BeanFactory:spring框架最核心的接口,是spring框架的基础设施,面向Spring。
1:提供IOC的配置机制
2:包含Bean的各种定义,便于实例化Bean。
3:建立对象的依赖关系。
4:Bean声明周期的控制。
BeanDefinition:描述Bean的定义。
BeanDefinitionRegistry:提供向IOC容易注册BeanDefinition对象的方法。 - ApplicationContext 面向使用Spring框架的开发者。继承多个接口
1:BeanFactory:能够管理、装配Bean
2:ResourcePatternResolver:能够加载资源文件
3:MessageResource:能够实现国际化等功能
4:ApplicationEventPublisher:能够注册监听器,实现监听机制。
Spring bean 的作用
- singleton:Spring的默认作用域,容器里拥有唯一的Bean实例。无状态的Bean
- prototype:针对每一个getBean请求,容器都会创建一个Bean实例。有状态的Bean。使用这种方式需要三思,频繁的创建和销毁Bean是需要开销的。
- request:会为每一个Http请求创建一个Bean实例。
- session:会为每一个session创建一个Bean实例。
- globalSession:会为每一全局Http Session创建一个Bean实例,该作用域仅对Portlet有效。
Spring Bean的声明周期
创建
- 实例化Bean
- Aware(注入Bean ID、BeanFactory和AppCtx)
- BeanPostProcessor(s).postProcessBeforeInitalization
- InitalizingBean(s).afterPropertiesSet
- 定制的Bean init方法
- BeanPostProcessor(s).postProcessAfterInitalization
- Bean初始化完成
销毁
- 实现了DisposableBean接口,会调用destroy方法。
- 配置destry-method属性,则会调用其配置的销毁方法。
还没有评论,来说两句吧...