【Spring 源码】ApplicationContext 容器的加载原理(三)
文章目录
一、BeanFactory 的后处理
(一) 调用 BeanFactoryPostProcessors
1. 使用 PropertyPlaceholderConfigurer
BeanFactoryPostProcessors 的经典例子就是使用 PropertyPlaceholderConfigurer,在平常使用 Spring 的时候经常能看到 xml 里面配置了 ${...}
这种变量引用,而实际调用的值则在 property 文件中。
比如在 xml 文件中使用了 ${bean.id}
变量引用,而 property 中则配置了 bean.id=12345
,这样过把整个 bean 打印出来,则可以打印出整个 bean 的内容来。
【1】配置方法
当然如果使用需要指定 property 文件的位置,而指定的方式有两种:
- 使用 context 标签的方式
此方法会默认使用 PropertySourcesPlaceholderConfigurer 来进行对${...}
占位符的解析。
<context:property-placeholder location="/configs/bean.properties"/>
- 普通 bean 的注册方式
此方法可以指定调用的类,在这边指定了 PropertyPlaceholderConfigurer,而如果是第一种方式,则会默认使用 PropertySourcesPlaceholderConfigurer。
<bean id="config" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>/configs/bean.properties</value>
</property>
</bean>
【2】简单例子
- 目录结构:
|-- src.main
|-- java.com.test
|-- Main.java
|-- MyBean.java
|-- resources
|-- configs
|-- bean.properties
|-- MyBean.xml
- MyBean.java:
public class MyBean {
private Integer beanId;
private String message;
private Double price;
public Integer getBeanId() {
return beanId;
}
public void setBeanId(Integer beanId) {
this.beanId = beanId;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
@Override
public String toString() {
return "MyBean{" +
"beanId=" + beanId +
", message='" + message + '\'' +
", price=" + price +
'}';
}
}
- MyBean.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="myBean" class="com.test.MyBean">
<property name="message" value="#{'Hello World!'}" />
<property name="price" value="#{10.1 + 20}" />
<property name="beanId">
<value>${bean.id}</value>
</property>
</bean>
<bean id="config" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>/configs/bean.properties</value>
</property>
</bean>
</beans>
- Main.java:
public class Main {
public static void main(String[] args) {
XmlBeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("MyBean.xml"));
MyBean bean = (MyBean) beanFactory.getBean("myBean");
System.out.println(bean.toString());
}
}
- bean.property:
bean.id=12345
- 结果:
MyBean{beanId=12345, message='Hello World!', price=30.1}
2. PropertyPlaceholderConfigurer 加载原理
【1】加载过程时序图
在 invokeBeanFactoryPostProcessors 加载过程中其实主要是设计到三个步骤:
- 获取 BeanDefinitionRegistryPostProcessor 或者 BeanFactoryPostProcessor 类型的 bean。
- 然后再对 bean 进行排序。
- 最后调用 BeanDefinitionRegistryPostProcessor 的
postProcessBeanDefinitionRegistry()
或者 BeanFactoryPostProcessor 的postProcessBeanFactory()
。
【2】加载过程源码
invokeBeanFactoryPostProcessors()
方法中会涉及到 BeanDefinitionRegistryPostProcessor 或者 BeanFactoryPostProcessor 两种类型的处理,上半部分主要处理 BeanDefinitionRegistryPostProcessor,下半部分则是处理 BeanFactoryPostProcessor。
BeanDefinitionRegistryPostProcessor 则是对 BeanFactoryPostProcessor 的扩展,而 BeanDefinitionRegistryPostProcessor 因为比 BeanFactoryPostProcessor 类型的 bean 先处理,因此 BeanDefinitionRegistryPostProcessor 的优先级更高。
BeanDefinitionRegistryPostProcessor 有一个实现的子类 ConfigurationClassPostProcessor,主要是用来处理使用 @Configuration
标记的 Bean,而 BeanFactoryPostProcessor 则是处理在 xml 文件中配置的 Bean。
调用 BeanFactoryPostProcessor
主要代码:AbstractApplicationContext#invokeBeanFactoryPostProcessors()
protected void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory
) {
// 处理 BeanFactoryPostProcessors
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
查找并调用 BeanFactoryPostProcessor
主要代码:PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors()
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory,
List<BeanFactoryPostProcessor> beanFactoryPostProcessors
) {
Set<String> processedBeans = new HashSet<>();
// 处理 BeanDefinitionRegistry 类型的 beanFactory
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// 已经注册过的 BeanFactoryPostProcessor
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
// 常规处理
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
// 常规处理
regularPostProcessors.add(postProcessor);
}
}
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// 获取注册过的 BeanDefinitionRegistryPostProcessor 类型的 bean
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
// 同时匹配实现 PriorityOrdered 接口的 bean
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
// 进行排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// 这边和上面的步骤差不多,只是筛选的对象从上面的 PriorityOrdered 改为了 Ordered 对象
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
// 进行排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// 这边还会在重复一次之前的操作,直到没有遗漏的
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
// 加载注册过的 Bean
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// 加载普通的 Bean
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// 获取 BeanFactoryPostProcessor 类型的 Bean
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// 跳过之前已经处理过的 Bean
}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// PriorityOrdered 排过序的
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
// Ordered 排过序的
orderedPostProcessorNames.add(ppName);
}
else {
// 无序的
nonOrderedPostProcessorNames.add(ppName);
}
}
// 先调用经过 PriorityOrdered 排序的
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 对经过 Ordered 排序的Bean
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// 调用普通的 BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// 清空缓存
beanFactory.clearMetadataCache();
}
在之前两种配置方式中,涉及到 PropertySourcesPlaceholderConfigurer 和 PropertyPlaceholderConfigurer,通过对两个类的继承图分析,可以发现其中都涉及到了抽象类 PlaceholderConfigurerSupport,其中抽象类实现了接口 BeanFactoryPostProcessor 中的 postProcessBeanFactory()
方法,在后续的 invokeBeanFactoryPostProcessors()
方法中会进行执行。
![[Pasted image 20220824121617.png]]
而 PlaceholderConfigurerSupport 的父级抽象类 PropertyResourceConfigurer 则默认实现了 postProcessBeanFactory()
方法。其中涉及到三个方法 mergeProperties()
,convertProperties()
和 processProperties()
。这三个方法分别是调用配置,转换值的类型以及对值进行处理然后告知 BeanFactory。
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
try {
// 获取配置
Properties mergedProps = mergeProperties();
// 转换值的类型,如果有需要可以使用子类重写
convertProperties(mergedProps);
// 子类执行调用,对配置的值进行处理
processProperties(beanFactory, mergedProps);
}
catch (IOException ex) {
throw new BeanInitializationException("Could not load properties", ex);
}
}
(二) 注册 BeanPostProcessors
注册 BeanPostProcessor 的方法会和上面的调用 BeanFactoryPostProcessors 过程类似,只不过换了 BeanPostProcessor 类型进行处理。
这边只是暂时将 BeanPostProcessor 类型的 Bean 添加到 AbstractBeanFactory 中的列表中,也就是进行 Bean 的注册,等待 bean 的实例化的时候进行调用。
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory,
AbstractApplicationContext applicationContext
) {
// 获取 BeanPostProcessor 类型的 Bean
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// 区分普通的、PriorityOrdered 和 Ordered 类型的 BeanPostProcessor
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// 进行排序
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 调用 ConfigurableListableBeanFactory#addBeanPostProcessor
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// 处理 Ordered 类型的 Bean
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// 处理普通类型的 Bean
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// 对 MergedBeanDefinitionPostProcessor 类型的 Bean 进行处理
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}