IoC
定义
IoC:控制反转。
DI:依赖注入。
核心思想:Spring 以“依赖注入”的方式实现了“控制反转”的效果,以符合软件工程中的“依赖倒置”原则。
设计
设计核心流程
- Bean 定义:Bean 通过 XML 或 @Component 注解标识,解析后被封装为
BeanDefinition
对象,存储类的元数据。 - BeanDefinition 加工:Bean 工厂后处理器,统一对 BeanDefinition 进行一些自定义操作。
- Spring 中,@Value 占位符解析就是通过 Bean 工厂后处理器实现的。
- Bean 实例化:反射。
- Bean 初始化:Spring 提供的一系列对 Bean 的增强方法,前置处理 -> 初始化 -> 后置处理。
- Bean 存储:初始化完成的 Bean 被存储进单例池中。
- Bean 销毁。
图解(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