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容器初始化过程的时序图如下:
image

我个人理解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初始化之后调用。

四胖儿
0 声望0 粉丝