IOC 概述
有这样一组对象:
public class Person{
private String name;
private int age;
private Address address;
public void setName(String name){this.name = name;}
public void setAge(int age){this.age = age;}
public void setAddress(Address address){this.address = address;}
}
public class Address{
private String birthAddress;
private String liveAddress;
public void setBirthAddress(String birthAddress){this.birthAddress = birthAddress;}
public void setLiveAddress(String liveAddress){this.liveAddress = liveAddress;}
}
在没有 IOC 概念之前可能咱们初始化对象的流程是这样:
... ...
Address address = new Address();
address.setBirthAddress("辽宁省");
address.setLiveAddress("北京市");
Person zhangSan = new Person();
zhanSan.setName("张三");
zhanSan.setAge(20);
zhanSan.setAddress(address);
... ...
须要本人手动初始化两个对象 zhangSan
、address
,同时须要将address
通过 setAddress
办法赋值。那如何不须要认为去初始化对象,而让开发者更关注业务实现。所以大神们提出 IOC 容器,IOC 管制反转也能够用依赖注入 (DI) 来形容它。我了解就是容器去负责初始化对象,并且将对象中相关联的属性注入对象,将对象初始化和依赖注入的控制权交给框架。
IOC 源码解析
以官网教程类为例,IOC 容器初始化过程的时序图如下:
我集体了解 IOC 初始化根本过程如下:
- 加载并解析配置文件。将配置文件中的 Bean 配置,封装成 BeanDefinition 对象并将其存入 IOC 容器的 beanDefinitionsNames(寄存 Bean 名字)和 beanDefiinitionsMap(以 Bean 名字为 key,已 BeanDefinition 为值)。
- 初始化 beanDefiinitionsMap 中存储的 BeanDefinition。
- 查看要初始化的 BeanDefinition 是否含有依赖属性。如果由将依赖属性初始化到 IOC 的 singletonObjects(key:bean name, value:bean 实例)汇合中。此过程是一个递归过程,如果依赖属性对象中还是由依赖持续递归初始化,直到依赖属性不含其余依赖属性为止。
- 将依赖属性注入到以后初始化的对象中,并存储到 singletonObjects,实现 IOC 初始化。
IOC 外围类
- BeanFactory:IOC 中的外围容器类,次要负责初始化对象和存储对象实例。
- BeanDefinition:次要用来形容 Bean 定义,我认为他次要用来与配置文件的 Bean 元素想对应,IOC 容器能够将配置文件的 Bean 元素封装成一个 BeanDefinition。
- BeanFactoryPostProcessor:容许自定义 BeanFactoryPostProcessor 实现类来批改 BeanDefinition。Spring IOC 中定义两种 BeanFactoryPostProcessor,一个是 BeanDefinitionRegistryPostProcessor,另一个是惯例的 BeanFactoryPostProcessor。BeanDefinitionRegistryPostProcessor 次要是用来扩大 BeanFactoryPostProcessor 性能,为其减少注册新 BeanDefinition 性能。例如 Spring 中 @configuration 等注解性能。
- BeanPostProcessor:容许自定义 BeanPostProcessor 实现类来批改 Bean 的实例对象。此接口中有
postProcessBeforeInitialization
和postProcessAfterInitialization
两个办法。postProcessBeforeInitialization
用于 Bean 初始化之前调用,postProcessAfterInitialization
用于 Bean 初始化之后调用。