0%

BeanFactoryProcessor

BeanFactoryProcessor

BeanFactoryPostProcessorspring中一个很重要的扩展点,它与BeanPostProcessor长相类似,触发点略有不同。BeanFactoryPostProcessor的作用时期是在所有bean实例化之前。所以它的作用是加载BeanDefinition。或者可以动态的修改或者是新增BeanDefinition

类图

BeanFactoryPostProcessor有一个扩展接口,这个扩展接口的方法会优先与BeanFactoryPostProcessor的方法执行。

BeanFactoryPostProcessor类图.png

源码

​ 还是从spring的核心方法refresh入手。其中的invokeBeanFactoryPostProcessors(beanFactory);就是用来处理BeanFactoryPostProcessor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
// 准备刷新容器操作(设置一些状态位,监听器、事件器)
prepareRefresh();

// Tell the subclass to refresh the internal bean factory.
// 实例化一个Bean工厂(DefaultListableBeanFactory)
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

// Prepare the bean factory for use in this context.
// 初始化BeanFactory, 进行一些属性的初始化赋值
prepareBeanFactory(beanFactory);

try {
// Allows post-processing of the bean factory in context subclasses.
// 空方法扩展点(springboot中有使用到)
postProcessBeanFactory(beanFactory);

// Invoke factory processors registered as beans in the context.
// 调用BeanFactoryPostProcessor ---> (在这里执行!!!)
invokeBeanFactoryPostProcessors(beanFactory);

// Register bean processors that intercept bean creation.
// 注册所有的BeanPostProcessor
registerBeanPostProcessors(beanFactory);

// Initialize message source for this context.
// 国际化
initMessageSource();

// Initialize event multicaster for this context.
// 初始化事件广播器
initApplicationEventMulticaster();

// Initialize other special beans in specific context subclasses.
// 扩展点, 由子类实现
onRefresh();

// Check for listener beans and register them.
// 注册事件监听器
registerListeners();

// Instantiate all remaining (non-lazy-init) singletons.
// 实例化所有的非懒加载的单例对象
finishBeanFactoryInitialization(beanFactory);

// Last step: publish corresponding event.
finishRefresh();
}

catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}

// Destroy already created singletons to avoid dangling resources.
destroyBeans();

// Reset 'active' flag.
cancelRefresh(ex);

// Propagate exception to caller.
throw ex;
}

finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}

核心的处理方法在PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors,源码处已有一些注释。这里简单描述一下整个流程。

第一步:参数中传递进来的 beanFactoryPostProcessors,由上述可知,这里可能是BeanDefinitionRegistryPostProcessor也可能是BeanFactoryPostProcessor的实现类。所以定义两个集合regularPostProcessorsregistryProcessors用于将二者分离开。这里会执行参数中传递进来的BeanDefinitionRegistryPostProcessor类型的接口。(在springboot中,可以在启动类的启动方法中添加)

第二步:获取容器中所有的BeanDefinitionRegistryPostProcessor,挑选出包含实现了PriorityOrdered接口的类,根据特定的排序规则进行排序后逐一执行。(在默认的情况下,这里仅会获取到ConfigurationClassPostProcessor,这里类的作用是处理配置类,将配置类[也就是开发者标记@Configuration@Component@ImportSelector等等]添加到容器中。)

第三步:获取容器中所有的BeanDefinitionRegistryPostProcessor,挑选出包含实现了Ordered接口的类,过滤执行过BeanDefinitionRegistryPostProcessor(若某个接口同时实现OrderedPriorityOrdered,则应该在第二步中执行),根据特定的排序规则进行排序后逐一执行。

第四步:获取容器中所有的BeanDefinitionRegistryPostProcessor,过滤已经执行过的,将剩下未执行的所有类,根据特定的排序规则进行排序后逐一执行。(这里使用死循环的原因:可能出现套娃情况,某个BeanDefinitionRegistryPostProcessor的实现方法中又创建了一个新的BeanDefinitionRegistryPostProcessor。)

以上便已经执行了容器中所有BeanDefinitionRegistryPostProcessor的扩展点。接下来就是执行BeanFactoryPostPostProcessor扩展点。

第五步:执行上述所有步骤中的BeanDefinitionRegistryPostProcessorBeanFactoryPostProcessor的实现接口。(就是扩展接口中的扩展方法已经都执行完了,在这个地方统一执行父接口中的实现方法。)

第六步:执行参数中传递进来的beanFactoryPostProcessors中仅实现BeanFactoryPostProcessor的实现接口。

第七步:(BeanFactoryPostPostProcessor的执行比较简单,用一步概括),获取容器中所有实现了BeanFactoryPostProcessor的类,将它们分为三类PriorityOrderedOrdered、和没有实现这两个接口的。然后分别根据排序规则进行排序后逐一执行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
/**
* 执行BeanFactoryPostProcessor扩展点
* 1. 执行BeanDefinitionRegistryPostProcessor的扩展点
* 1.1. 执行参数beanFactoryPostProcessors中是BeanDefinitionRegistryPostProcessor的实现类的扩展点
* 1.2. 执行spring容器中的BeanDefinitionRegistryPostProcessor的实现且依次@PriorityOrdered@Ordered
* 1.3. 执行容器中还存在BeanDefinitionRegistryPostProcessor实现但未加入已执行集合(registryProcessors)中的实现类
* 2. 执行BeanDefinitionPostProcessor的扩展点
* 2.1. 执行非直接实现BeanDefinitionRegistryPostProcessor集合(registryProcessors)的BeanFactoryPostProcessor的扩展点
* 2.2. 执行直接实现BeanFactoryPostProcessor集合(regularPostProcessors)的BeanFactoryPostProcessor的扩展点(这个集合中若存在
* 元素, 则是开发者通过调用参数携带进来, 在第一步骤执行是分离出来)
* 2.3. 执行spring容器中还未执行的BeanFactoryPostProcessor、顺序依次为@PriorityOrdered@Ordered、最后是没有标记前者两注解的
* BeanFactoryPostProcessor的实现类
*
* @Author: xiaocainiaoya
* @Date: 2021/06/09 10:05:09
* @param beanFactory
* @param beanFactoryPostProcessors 这个是自定义的beanFactoryPostProcessors, 默认是空的, 除非自己扩展
* @return:
**/
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

// Invoke BeanDefinitionRegistryPostProcessors first, if any.
//处理过的BeanDefinitionRegistryPostProcessors类型的bean名字集合
Set<String> processedBeans = new HashSet<>();

if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
// 常规postProcessor(直接实现BeanFactoryPostProcessor的实现类)集合
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
// registryProcessor(非直接实现BeanFactoryPostProcessor的实现类)且已经调用过扩展点的集合
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

// BeanFactoryPostProcessor是BeanDefinitionRegistryPostProcessor的父接口, 执行beanFactoryPostProcessors中的BeanDefinitionRegistryPostProcessor
// 并将执行过后的BeanDefinitionRegistryPostProcessor放置在registryProcessors, 将未执行的BeanFactoryPostProcessor添加到regularPostProcessors
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor;
// 调用BeanDefinitionRegistryPostProcessor扩展点
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}else {
// 直接实现了BeanFactoryPostProcessor接口的实现
regularPostProcessors.add(postProcessor);
}
}

// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// Separate between BeanDefinitionRegistryPostProcessors that implement
// PriorityOrdered, Ordered, and the rest.
// 放内部的BeanDefinitionRegistryPostProcessor后置处理器
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
// 首先, 调用实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessors
// (若没有改造或者二次开发过, 此处只会返回ConfigurationClassPostProcessor类
// ConfigurationClassPostProcessor类的作用是加载配置类)
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
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);
// 执行BeanDefinitionRegistryPostProcessors扩展点
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();

// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
// 其次, 调用仅实现了Ordered接口的BeanDefinitionRegistryPostProcessors
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
// 过滤调用过的processedBean
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();

// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
// 最后, 调用processedBeans中没有标记过的BeanDefinitionRegistryPostProcessors
// 这个while循环是由于可能出现套娃的情况: 比如A类实现了BeanDefinitionRegistryPostProcessor, 在调用A的
//postProcessBeanDefinitionRegistry中又添加了一个BeanDefinitionRegistryPostProcessor类B。
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();
}

// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
} else {
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}

// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// 不要在此处初始化 FactoryBeans:我们需要保留所有未初始化的常规bean,让 bean 工厂后处理器应用于它们!
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}

// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

// Finally, invoke all other BeanFactoryPostProcessors.
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
beanFactory.clearMetadataCache();
}

例子

​ 从spring的生命周期看BeanFactoryPostProcessor的执行时机就是在BeanPostProcessor注册之前,甚至可以说是在大部分的bean注入之前。但若大量使用BeanFactoryPostProcessor进行扩展,若有重叠区域,则需考虑执行的先后顺序。比如后期的扩展是否需要控制新的BeanFactoryPostProcessor要在旧BeanFactoryPostProcessor之前或者之后?这个执行顺序是一个很容易忽略的关键点(自定义的BeanFactoryPostProcessor可以通过实现Order接口控制执行顺序)

实例1

​ 可以通过BeanDefinitionRegistryPostProcessor修改BeanDefinition,比如在业务场景中有非常多的地方使用的是名称注入的方式,现要让这个名称注入容器中的类由新类,替换旧类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {

@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
/**
* 替换class
*/
// 获取扫描路径下的旧类
BeanDefinition beanDefinition = registry.getBeanDefinition("roomService");
// 使其指向新类
beanDefinition.setBeanClassName("cn.com.xiaocainiaoya.service.NewRoomService");
}

@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

}
}

实例2

springframwork的扫描工作中比较核心的类ConfigurationClassPostProcessor,这个类的作用就是扫描配置类,扫描指定路径下的各种配置注解@ConfigurationComponentComponentScan等等。将这些类解析后添加到BeanDefinition中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/**
* 从注册表中的配置类派生进一步的 bean 定义。简单说根据BeanDefinition将配置类添加到spring容器中
* 1. 完成扫描
* 2. 对配置类的定义, 完成对配置类的标记
* 3. 对import的处理
* 3.1 ImportSelector(在springboot中自动装配典型使用)
* 3.2 ImportBeanDefinitionRegistrar(在mybatis中典型使用)
* 3.3 普通类
* 3.3.1 没有任何特殊注解
* 3.3.2 加了Import
* 3.4 ImportResource
* 4. @Bean的处理
* 5. 接口当中的@Bean
* 6. @PropertySource的处理
* 7. 内部类的处理
* 8. 父类的处理
*
* Derive further bean definitions from the configuration classes in the registry.
*/
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
// 生成一个id,放置后面再重复执行
int registryId = System.identityHashCode(registry);

// 若重复执行 就抛出异常
if (this.registriesPostProcessed.contains(registryId)) {
throw new IllegalStateException("postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
}
if (this.factoriesPostProcessed.contains(registryId)) {
throw new IllegalStateException("postProcessBeanFactory already called on this post-processor against " + registry);
}

// 表示此registry里的BeanDefinition收集动作,已经做了 避免再重复收集此registry
this.registriesPostProcessed.add(registryId);

// 根据配置类,收集到所有的bd信息,并且做出mark标注:是Full模式还是Lite模式
processConfigBeanDefinitions(registry);
}

注意事项

BeanFactoryPostProcessor算是spring给予开发者很高的权限去处理BeanDefinitions,但使用的过程中还需遵守spring的规范,不可将bean实例化,即不可在BeanFactoryPostProcessor中触发bean实例化的操作。比如:

1
2
3
4
5
6
7
8
9
10
11
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
// 这个getBeansOfType调用会触发getBean方法,会导致Bean提前注入,而在生命周期的这个节点
// 自动注入的BeanPostProcessor还没有注入,还不会作用在bean的创建过程中,所以会导致
// RoomService的属性注入会失效。
Map<String, RoomService> map = beanFactory.getBeansOfType(RoomService.class);
}
}

所以,在BeanFactoryPostProcessor的使用中切记要确保不会触发Bean的提前实例化。

-------------本文结束感谢您的阅读-------------