精通Spring4.x-chapter6

Spring容器技术内幕

工作机制

spring的AbstractApplicationContext是ApplicationContext的抽象实现类,其中的refresh()方法定义了容器在加载文件后的各项处理过程

//初始化BeanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

//调用工厂后处理器
invokeBeanFactoryPostProcessors();

//注册Bean后处理器
registerBeanPostProcessors();

//初始化消息源
initMessageSource();

//初始化应用上下文事件广播器
initApplicationEventMulticaster();

//初始化其他特殊的Bean:由具体子类实现
onRefresh();

//注册事件监听器
registerListeners();

//初始化所有单例的Bean,使用懒加载模式的Bean除外
finishBeanFactoryInitialization(beanFactory);

//完成刷新并发布容器刷新事件
finishRefresh();

Spring组件:

(1)被加工的组件:Resource、BeanDefinition、PropertyEditor和最终的Bean

(2)加工设备:ResourceLoader、BeanDefinitionReader、BeanFactoryPostProcessor、InstanitiationStrategy和BeanWrapper

BeanDefinition

BeanDefinition是配置文件< bean >元素标签在容器中的内部表示

< bean >拥有class、scope、lazy-init等配置属性,对应的BeanDefinition提供了beanClass、scope、lazy-Init类属性

父< bean >用RootBeanDefiniton表示,子< bean >用ChildBeanDefiniton表示,而没有父< bean >的< bean >用RootBeanDefiniton表示。

Spring通过BeanDefinition将配置文件中的< bean >配置信息转换为容器的内部表示,并将它们注册到BeanDefinitionRegistry中,便于后续操作读取配置信息。一般在容器启动时加载并解析BeanDefinition。

创建最终BeanDefinition的步骤

首先利用BeanDefinitionReader读取承载配置信息的Resource,通过XML解析器解析配置信息的DOM对象,简单生成对应< bean >的BeanDefinition对象。由于在配置文件中,可能通过占位符变量引用外部属性文件的属性,因此只是半成品

接着利用容器中注册的BeanFactoryPostProcessor对半成品的BeanDefinition进行加工处理,将以占位符表示的配置解析为最终的实际值

InstantiationStrategy

根据BeanDefinition对象创建一个Bean实例

SimpleInstantiationStrategy策略利用Bean实现类的默认构造函数、带参构造函数或工厂方法创建Bean的实例

CglibSubclassingInstantiationStrategy利用CGLib类库为Bean动态生成子类,在子类生成方法注入的逻辑,接着使用这个子类创建Bean实例

InstantiationStrategy仅负责实例化Bean的操作,相当于执行new功能,并不参与Bean属性的设置工作。因此返回的Bean实例时半成品,接下来要BeanWrapper完成属性填充

BeanWrapper

Spring委托BeanWrapper完成Bean属性的填充工作

BeanWrapper有两个顶级接口,PropertyAccessor接口定义了各种访问Bean属性的方法,而PropertyEditorRegistry时属性编辑器的注册表

因此实现类BeanWrapperImpl身份有Bean包裹器、属性访问器和属性编辑器注册表

一个BeanWrapperImpl实例内部封装了目标Bean实例和属性编辑器,填充属性还需要从BeanDefinitionRegistry获取Bean对应的BeanDefiniton

Spring主控程序从BeanDefinition获取Bean属性的配置信息PropertyValue,并使用属性编辑器对PropertyValue进行转换以得到Bean的属性值。

属性编辑器

属性编辑器的功能是将外部的设置值转换为JVM内部的对应类型,即类型转换器