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);... ...

须要本人手动初始化两个对象zhangSanaddress,同时须要将address通过setAddress办法赋值。那如何不须要认为去初始化对象,而让开发者更关注业务实现。所以大神们提出IOC容器,IOC管制反转也能够用依赖注入(DI)来形容它。我了解就是容器去负责初始化对象,并且将对象中相关联的属性注入对象,将对象初始化和依赖注入的控制权交给框架。

IOC源码解析

以官网教程类为例,IOC容器初始化过程的时序图如下:

我集体了解IOC初始化根本过程如下:

  1. 加载并解析配置文件。将配置文件中的Bean配置,封装成BeanDefinition对象并将其存入IOC容器的beanDefinitionsNames(寄存Bean名字)和beanDefiinitionsMap(以Bean名字为key,已BeanDefinition为值)。
  2. 初始化beanDefiinitionsMap中存储的BeanDefinition。
  3. 查看要初始化的BeanDefinition是否含有依赖属性。如果由将依赖属性初始化到IOC的singletonObjects(key:bean name, value:bean实例)汇合中。此过程是一个递归过程,如果依赖属性对象中还是由依赖持续递归初始化,直到依赖属性不含其余依赖属性为止。
  4. 将依赖属性注入到以后初始化的对象中,并存储到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的实例对象。此接口中有postProcessBeforeInitializationpostProcessAfterInitialization两个办法。postProcessBeforeInitialization用于Bean初始化之前调用,postProcessAfterInitialization用于Bean初始化之后调用。