Skip to content

IoC

定义

IoC:控制反转。

DI:依赖注入。

核心思想:Spring 以“依赖注入”的方式实现了“控制反转”的效果,以符合软件工程中的“依赖倒置”原则。

设计

设计核心流程

  • Bean 定义:Bean 通过 XML 或 @Component 注解标识,解析后被封装为 BeanDefinition 对象,存储类的元数据。
  • BeanDefinition 加工:Bean 工厂后处理器,统一对 BeanDefinition 进行一些自定义操作。
    • Spring 中,@Value 占位符解析就是通过 Bean 工厂后处理器实现的。
  • Bean 实例化:反射。
  • Bean 初始化:Spring 提供的一系列对 Bean 的增强方法,前置处理 -> 初始化 -> 后置处理。
  • Bean 存储:初始化完成的 Bean 被存储进单例池中。
  • Bean 销毁。

图解(Bean 的生命周期)

Spring-Bean生命周期

图中可以看出,Spring 中主要有两个容器

  • beanDefinitionMap:存储 BeanDefinition
  • singletonObjects:存储 Bean 实例。

BeanDefinition阶段

相关类

BeanDefinition 存储 Bean 的 Class 字节码、成员变量与一些元数据(作用域、初始化方法、销毁方法、是否懒加载等)。

classDiagram
    class DefaultListableBeanFactory{
        -Map~String, BeanDefinition~ beanDefinitionMap
    }
    class BeanDefinition{
        -Class beanClass
        -MutablePropertyValues propertyValues
        -boolean singleton
        -boolean prototype
        -String initMethodName
        -String destroyMethodName
        -boolean lazyInit
    }
    class MutablePropertyValues{
        -List~PropertyValue~ propertyValueList
    }
    class PropertyValue{
        -String name
        -Object value
    }
    DefaultListableBeanFactory *-- BeanDefinition
    BeanDefinition *-- MutablePropertyValues
    MutablePropertyValues *-- PropertyValue

注册BeanDefinition

通过 XML 或注解的方式将 Bean 相关信息存储进 BeanDefinition

  • XML:解析 XML 文件。

    // 1. 创建 Bean 容器
    DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
    // 2. 创建 XML 读取器
    XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
    // 3. 读取器解析 XML 文件,封装为 BeanDefinition,存储进 Bean 容器
    beanDefinitionReader.loadBeanDefinitions("classpath:spring.xml");
    
  • 注解:扫描所有类,为实现 @Component 的类注册 BeanDefinition

    • 相关类:ClassPathBeanDefinitionScanner

Bean实例化&初始化阶段

sequenceDiagram
    participant BF as BeanFactory
    participant BF2 as BeanFactory
    participant BPP as BeanPostProcessor
    participant C as 类

    note over BF: AOP相关暂时还没搞
    BF->>+BF: doCreateBean
    BF->>+BF2: createBeanInstance<br>实例化Bean
    note over C: SimpleInstantiationStrategy
    BF2->>-C: instantiate<br>通过newInstance简单实例化Bean的无参构造函数
    activate C
    C-->>BF: 返回Bean实例
    deactivate C
    BF->>BF2: applyBeanPostprocessorsBeforeApplyingPropertyValues<br>Aware相关
    BF->>+BF2: applyPropertyValues<br>填充属性<br>将BeanDefinition中的属性填充到Bean实例中
    BF2-->>-BF: 返回填充属性后的Bean实例
    BF->>+BF2: initializeBean<br>初始化方法
    BF2->>+BF2: applyBeanPostProcessorsBeforeInitialization
    BF2->>-BPP: postProcessBeforeInitialization
    BF2->>+BF2: invokeInitMethods<br>初始化方法<br>如果实现了InitializingBean接口,则调用其方法实现
    note over C: InitializingBean<br>实现该接口的Bean
    BF2->>-C: afterPropertiesSet
    BF2->>BF2: applyBeanPostProcessorsAfterInitialization
    activate BF2
    BF2->>-BPP: postProcessAfterInitialization
    BF2-->>BF: 返回经过一系列处理的Bean实例
    deactivate BF2
    BF->>-BF2: registerDisposableBeanIfNecessary<br>销毁方法
    activate BF2
    note over C: DisposableBean<br>实现该接口的Bean
    BF2->>C: destroy
    deactivate BF2

ApplicationContext

ApplicationContext 相比与 BeanFactory,增强在于“自动化配置”与“企业级特性”。

  • 自动化配置:refreshBeanFactory 默认容器初始化,而 BeanFactory 需要手动配置。
  • 企业级特性:国际化、资源访问、环境抽象、事件发布等。(未实现)

时序图:

容器默认初始化,这部分逻辑一开始就被执行,随后才是 Bean 的实例化&初始化阶段。

sequenceDiagram
    participant AC as ApplicationContext
    participant AC2 as ApplicationContext
    participant C as 类

    AC->>AC: refresh
    activate AC
    AC->>+AC2: refreshBeanFactory
    AC2->>C: new DefaultListableBeanFactory
    AC2->>C: new XmlBeanDefinitionReader(beanFactory)
    AC2->>-C: loadBeanDefinitions(config)
    AC->>+AC2: invokeBeanFactoryPostProcessors<br>执行Bean工厂后处理器
    note over C: BeanFactoryPostProcessor
    AC2->>-C: postProcessBeanFactory
    AC->>AC2: registerBeanPostProcessors<br>缓存Bean后处理器
    deactivate AC