抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

Spring源码分析-调用BeanPostProcessor

前言

​ 前几篇已经完成了obtainFreshBeanFactory方法的调用,已经完成了XML的解析以及注册就完成了,但是如果注册的bean不符合需要呢,需要一些处理,对注册的BeanDefinition做一些变更怎么办呢,这就要用到今天讲的BeanFactor后置处理器,是invokeBeanFactoryPostProcessors方法,他会在注册完成BeanDefinition紧接着就会调用该方法,完成注册的BeanDefinition的修改操作。

​ invokeBeanFactoryPostProcessors 方法主要用于处理 BeanFactoryPostProcessor 接口,而 registerBeanPostProcessors 方法主要用于处理 BeanPostProcessor 接口。BeanFactoryPostProcessor 和 BeanPostProcessor,相信大家很容易从命名看出来这两个接口“长得很像”。BeanFactoryPostProcessor 是针对 BeanFactory 的扩展,主要用在 bean 实例化之前,读取 bean 的定义,并可以修改它。BeanPostProcessor 是针对 bean 的扩展,主要用在 bean 实例化之后,执行初始化方法前后,允许开发者对 bean 实例进行修改。

概述

​ 本方法会注册所有的 BeanPostProcessor,将所有实现了 BeanPostProcessor 接口的类加载到 BeanFactory 中。

​ BeanPostProcessor 接口是 Spring 初始化 bean 时对外暴露的扩展点,Spring IoC 容器允许 BeanPostProcessor 在容器初始化 bean 的前后,添加自己的逻辑处理。在 registerBeanPostProcessors 方法只是注册到 BeanFactory 中,具体调用是在 bean 初始化的时候。

​ 具体的:在所有 bean 实例化时,执行初始化方法前会调用所有 BeanPostProcessor 的postProcessBeforeInitialization 方法,在执行初始化方法后会调用所有 BeanPostProcessor 的 postProcessAfterInitialization 方法。

invokeBeanFactoryPostProcessors

invokeBeanFactoryPostProcessors

这个方法在refresh方法内部在obtainFreshBeanFactory后面,将完成注册的BeanDefinition进行修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* Instantiate and invoke all registered BeanFactoryPostProcessor beans,
* respecting explicit order if given.
* <p>Must be called before singleton instantiation.
* <p>
* 可以对调用的解析并注册的BeanDefinition进行修改或者新增
*/
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// 1.getBeanFactoryPostProcessors(): 拿到当前应用上下文beanFactoryPostProcessors变量中的值
// 2.invokeBeanFactoryPostProcessors: 实例化并调用所有已注册的BeanFactoryPostProcessor
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}

getBeanFactoryPostProcessor

1
2
3
4
5
6
7
8
/**
* Return the list of BeanFactoryPostProcessors that will get applied
* to the internal BeanFactory.
* 获取所有注册的beanFactoryPostProcessors
*/
public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
return this.beanFactoryPostProcessors;
}

​ 这边 getBeanFactoryPostProcessors() 会拿到当前应用上下文中已经注册的 BeanFactoryPostProcessor,在默认情况下,this.beanFactoryPostProcessors 是返回空的。

invokeBeanFactoryPostProcessors

来到PostProcessorRegistrationDelegate类

他会调用公共类PostProcessorRegistrationDelegate的invokeBeanFactoryPostProcessors方法

主要的调用PostProcessor接口的入口进行实例化之前的操作

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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
/**
* 主要的调用PostProcessor接口的入口进行实例化之前的操作
*
* @param beanFactory
* @param beanFactoryPostProcessors
*/
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

//优先调用BeanDefinitionRegistryPostProcessors进行注册
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<>();
// 1.判断beanFactory是否为BeanDefinitionRegistry,beanFactory为DefaultListableBeanFactory,
// 而DefaultListableBeanFactory实现了BeanDefinitionRegistry接口,因此这边为true
if (beanFactory instanceof BeanDefinitionRegistry) {
//将beanFactory转换为BeanDefinitionRegistry
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
// 用于存放BeanDefinitionRegistryPostProcessor
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
// 用于存放普通的BeanFactoryPostProcessor
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

// 2.首先处理入参中的beanFactoryPostProcessors
// 遍历所有的beanFactoryPostProcessors, 将BeanDefinitionRegistryPostProcessor和普通BeanFactoryPostProcessor区分开
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
// 2.1 如果实现了BeanDefinitionRegistryPostProcessor接口
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
//转换为BeanDefinitionRegistryPostProcessor类型
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
// 2.1.1 直接执行BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry方法
registryProcessor.postProcessBeanDefinitionRegistry(registry);
// 2.1.2 添加到registryProcessors(用于最后执行postProcessBeanFactory方法)
registryProcessors.add(registryProcessor);
} else {
// 2.2 否则,只是普通的BeanFactoryPostProcessor
// 2.2.1 添加到regularPostProcessors(用于最后执行postProcessBeanFactory方法)
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<>();

// 3.调用所有实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor实现类
// 3.1 找出所有实现BeanDefinitionRegistryPostProcessor接口的Bean的beanName
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);

// 3.2 遍历postProcessorNames
for (String ppName : postProcessorNames) {
// 3.3 校验是否实现了PriorityOrdered接口
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 3.4 获取ppName对应的bean实例, 添加到currentRegistryProcessors中,
// beanFactory.getBean: 这边getBean方法会触发创建ppName对应的bean对象, 目前暂不深入解析
//因为需要进行调用所以先获取BeanDefinitionRegistryPostProcessor类型的实例并添加到currentRegistryProcessors
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
// 3.5 将要被执行的加入processedBeans,避免后续重复执行
processedBeans.add(ppName);
}
}
// 3.6 进行排序(根据是否实现PriorityOrdered、Ordered接口和order值来排序)
sortPostProcessors(currentRegistryProcessors, beanFactory);
// 3.7 添加到registryProcessors(用于最后执行postProcessBeanFactory方法)
registryProcessors.addAll(currentRegistryProcessors);

// 3.8 遍历currentRegistryProcessors, 执行postProcessBeanDefinitionRegistry方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
// 3.9 执行完毕后, 清空currentRegistryProcessors
currentRegistryProcessors.clear();

// 4.调用所有实现了Ordered接口的BeanDefinitionRegistryPostProcessor实现类(过程跟上面的步骤3基本一样)
// 4.1 找出所有实现BeanDefinitionRegistryPostProcessor接口的类, 这边重复查找是因为执行完上面的BeanDefinitionRegistryPostProcessor,
// 可能会新增了其他的BeanDefinitionRegistryPostProcessor, 因此需要重新查找
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
// 校验是否实现了Ordered接口,并且还未执行过
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
//因为需要进行调用所以先获取BeanDefinitionRegistryPostProcessor类型的实例并添加到currentRegistryProcessors
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
//将BeanDefinition对象的beanName添加到processedBeans
processedBeans.add(ppName);
}
}
//完成排序工作
sortPostProcessors(currentRegistryProcessors, beanFactory);
//添加到registryProcessors
registryProcessors.addAll(currentRegistryProcessors);
// 4.2 遍历currentRegistryProcessors, 执行postProcessBeanDefinitionRegistry方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
//再次清空currentRegistryProcessors
currentRegistryProcessors.clear();

// 5.最后, 调用所有剩下的BeanDefinitionRegistryPostProcessors
//没实现排序接口的调用
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
boolean reiterate = true;
while (reiterate) {
//如果所以的BeanDefinitionRegistryPostProcessor都调用过了就退出循环
reiterate = false;
//5.1 获取实现了BeanDefinitionRegistryPostProcessor接口的所有类的BeanDefinition对象的beanName
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
//遍历postProcessorNames
for (String ppName : postProcessorNames) {
// 5.2 跳过已经执行过的
//如果以上两次都没有调用过的BeanDefinitionRegistryPostProcessor走下面的判断
if (!processedBeans.contains(ppName)) {
//因为需要进行调用所以先获取BeanDefinitionRegistryPostProcessor类型的实例并添加到currentRegistryProcessors
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
//将BeanDefinition对象的beanName添加到processedBeans
processedBeans.add(ppName);
//如果有调用的再次循环
// 5.3 如果有BeanDefinitionRegistryPostProcessor被执行, 则有可能会产生新的BeanDefinitionRegistryPostProcessor,
// 因此这边将reiterate赋值为true, 代表需要再循环查找一次
reiterate = true;
}
}
//完成排序工作
sortPostProcessors(currentRegistryProcessors, beanFactory);
//添加到registryProcessors
registryProcessors.addAll(currentRegistryProcessors);
// 5.4 遍历currentRegistryProcessors, 执行postProcessBeanDefinitionRegistry方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
//再次清空currentRegistryProcessors
currentRegistryProcessors.clear();
}

//如果registryProcessors不为空的话最后一次完成一次调用
// 6.调用所有BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法(BeanDefinitionRegistryPostProcessor继承自BeanFactoryPostProcessor)
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
// 7.最后, 调用入参beanFactoryPostProcessors中的普通BeanFactoryPostProcessor的postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
} else {
// Invoke factory processors registered with the context instance.
//完成BeanFactoryPostProcessor的调用
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}

// 到这里 , 入参beanFactoryPostProcessors和容器中的所有BeanDefinitionRegistryPostProcessor已经全部处理完毕,
// 下面开始处理容器中的所有BeanFactoryPostProcessor
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// 8.找出所有实现BeanFactoryPostProcessor接口的类
//获取实现了BeanFactoryPostProcessor接口的类,获取beanDefinition的名称
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
// 用于存放实现了PriorityOrdered接口的BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
// 用于存放实现了Ordered接口的BeanFactoryPostProcessor的beanName
List<String> orderedPostProcessorNames = new ArrayList<>();
// 用于存放普通BeanFactoryPostProcessor的beanName
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
// 8.1 遍历postProcessorNames, 将BeanFactoryPostProcessor按实现PriorityOrdered、实现Ordered接口、普通三种区分开
for (String ppName : postProcessorNames) {
// 8.2 跳过已经执行过的,如果上面步骤已经调用过的BeanDefinition跳过
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
//实现了PriorityOrdered接口的
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 8.3 添加实现了PriorityOrdered接口的BeanFactoryPostProcessor
//实例化BeanFactoryPostProcessor并添加到priorityOrderedPostProcessors
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
//实现了Ordered接口的
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
// 8.4 添加实现了Ordered接口的BeanFactoryPostProcessor的beanName
orderedPostProcessorNames.add(ppName);
} else {
// 8.5 添加剩下的普通BeanFactoryPostProcessor的beanName
nonOrderedPostProcessorNames.add(ppName);
}
}

// 9.调用所有实现PriorityOrdered接口的BeanFactoryPostProcessor
// 9.1 对priorityOrderedPostProcessors排序
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 9.2 遍历priorityOrderedPostProcessors, 执行postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

// 10.调用所有实现Ordered接口的BeanFactoryPostProcessor
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());

//将所有实现了Ordered接口的类加入到orderedPostProcessors用来排序
for (String postProcessorName : orderedPostProcessorNames) {
// 10.1 获取postProcessorName对应的bean实例, 添加到orderedPostProcessors, 准备执行
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}

// 10.2 对orderedPostProcessors排序
sortPostProcessors(orderedPostProcessors, beanFactory);
// 10.3 遍历orderedPostProcessors, 执行postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

// 11.调用所有剩下的BeanFactoryPostProcessor
//没有实现任何排序接口的BeanFactoryPostProcessor操作
// Finally, invoke all other BeanFactoryPostProcessors.
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
//遍历并添加到nonOrderedPostProcessors
for (String postProcessorName : nonOrderedPostProcessorNames) {
// 11.1 获取postProcessorName对应的bean实例, 添加到nonOrderedPostProcessors, 准备执行
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
// 11.2 遍历nonOrderedPostProcessors, 执行postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
// 12.清除元数据缓存(mergedBeanDefinitions、allBeanNamesByType、singletonBeanNamesByType),
// 因为后处理器可能已经修改了原始元数据,例如, 替换值中的占位符...
beanFactory.clearMetadataCache();
}

​ 判断 beanFactory 是否为 BeanDefinitionRegistry。beanFactory 是在之前的 obtainFreshBeanFactory 方法构建的,具体代码在:AbstractRefreshableApplicationContext.refreshBeanFactory() 方法,代码如下

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
@Override
protected final void refreshBeanFactory() throws BeansException {
//如果BeanFactory不为空,则清除BeanFactory和里面的实例
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
//创建DefaultListableBeanFactory

//BeanFactory 实例工厂 上下文和BeanFactory的区别
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());

//设置是否可以循环依赖 allowCircularReferences
//是否允许使用相同名称重新注册不同的bean实现.
customizeBeanFactory(beanFactory);

//解析Spring配置文件,并把xml中的标签封装成BeanDefinition对象
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
} catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}

​ 可以看出,我们构建的 beanFactory 是一个 DefaultListableBeanFactory ,而 DefaultListableBeanFactory 实现了BeanDefinitionRegistry 接口,因此 beanFactory instanceof BeanDefinitionRegistry 结果为 true。

sortPostProcessors

对PostProcessors进行排序,值越小越优先

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* 进行排序操作 越小越优先
*
* @param postProcessors
* @param beanFactory
*/
private static void sortPostProcessors(List<?> postProcessors, ConfigurableListableBeanFactory beanFactory) {
Comparator<Object> comparatorToUse = null;
if (beanFactory instanceof DefaultListableBeanFactory) {
// 1.获取设置的比较器
comparatorToUse = ((DefaultListableBeanFactory) beanFactory).getDependencyComparator();
}
if (comparatorToUse == null) {
// 2.如果没有设置比较器, 则使用默认的OrderComparator
comparatorToUse = OrderComparator.INSTANCE;
}
// 3.使用比较器对postProcessors进行排序
postProcessors.sort(comparatorToUse);
}

​ 默认情况下,比较器为 OrderComparator;如果配置了 annotation-config,并且值为true,使用的是 AnnotationAwareOrderComparator,AnnotationAwareOrderComparator 继承自 OrderComparator,只是重写了部分方法,比较器的部分代码如下:

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
@Override
public int compare(Object o1, Object o2) {
return doCompare(o1, o2, null);
}

private int doCompare(Object o1, Object o2, OrderSourceProvider sourceProvider) {
// 判断o1是否实现了PriorityOrdered接口
boolean p1 = (o1 instanceof PriorityOrdered);
// 判断o2是否实现了PriorityOrdered接口
boolean p2 = (o2 instanceof PriorityOrdered);
// 1.如果o1实现了PriorityOrdered接口, 而o2没有, 则o1排前面
if (p1 && !p2) {
return -1;
}
// 2.如果o2实现了PriorityOrdered接口, 而o1没有, 则o2排前面
else if (p2 && !p1) {
return 1;
}

// 3.如果o1和o2都实现(都没实现)PriorityOrdered接口
// Direct evaluation instead of Integer.compareTo to avoid unnecessary object creation.
// 拿到o1的order值, 如果没实现Ordered接口, 值为Ordered.LOWEST_PRECEDENCE
int i1 = getOrder(o1, sourceProvider);
// 拿到o2的order值, 如果没实现Ordered接口, 值为Ordered.LOWEST_PRECEDENCE
int i2 = getOrder(o2, sourceProvider);
// 4.通过order值(order值越小, 优先级越高)排序
return (i1 < i2) ? -1 : (i1 > i2) ? 1 : 0;
}

​ 比较器的逻辑很简单,实现 PriorityOrdered 接口的优先级最高,如果两个对象都实现(都没实现)PriorityOrdered 接口,则根据 order 值(实现 Ordered 接口时,需要实现 getOrder() 方法,返回 order 值)来进行比较,order 值越小,优先级越高。

小结

这个类比较大,我们分几部分两讲解

  1. 如果实现了BeanDefinitionRegistry将进行注册操作,这一部分将在讲解AnnotationConfigApplicationContext注册过程中讲到
  2. 获取所有的实现BeanDefinitionRegistryPostProcessor接口的实现类
  3. 实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor的类进行排序,这一部分比较简单不需要讲了
  4. 调用BeanDefinitionRegistryPostProcessor接口的过程(重点)
  5. 获取所有的BeanFactoryPostProcessor接口的实现类
  6. 对实现PriorityOrdered排序接口Ordered排序接口的BeanFactoryPostProcessor的实现类进行排序
  7. 完成对BeanFactoryPostProcessor接口实现类的调用(重点)

BeanDefinitionRegistryPostProcessor实现类的收集

主要完成了对实现BeanDefinitionRegistryPostProcessor接口的类的收集

1
2
3
4
//获取实现了BeanDefinitionRegistryPostProcessor接口的所有类的BeanDefinition对象的beanName
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);

小结

主要调用getBeanNamesForType方法完成从按照Type类型的收集

最终会调用到doGetBeanNamesForType方法,会对注册的到beanDefinitionNames的beanName进行遍历,根据beanName从beanDefinitionMap中获取BeanDefinition判断beanClass的类型是否实现了BeanDefinitionRegistryPostProcessor接口。

完成BeanDefinitionRegistryPostProcessor接口的调用

调用invokeBeanDefinitionRegistryPostProcessors方法完成BeanDefinitionRegistryPostProcessor接口的调用,主要完成BeanDefinition的注册,主要有两个实现类

ConfigurationClassPostProcessor:实现了对@ComponentScan注解的支持,完成bean的扫描。

这是一个扩展点,如果我需要使用java代码注册bean到spring,就可以实现该接口进行扩展

1
2
3
4
5
6
7
8
9
10
11
12
/**
* Invoke the given BeanDefinitionRegistryPostProcessor beans.
* 调用实现了BeanDefinitionRegistryPostProcessor接口的bean,完成对注册的BeanDefinition的修改
*/
private static void invokeBeanDefinitionRegistryPostProcessors(
Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
//遍历调用BeanDefinitionRegistryPostProcessor
for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
//完成调用过程
postProcessor.postProcessBeanDefinitionRegistry(registry);
}
}
ConfigurationClassPostProcessor

这个类是Spring中最强大的类,实现了对有 @Configuration、@Import 、 @Component、@ComponentScan 以及 @ImportResource 主机的支持

具体请参考《Configuration注解的支持》

完成BeanFactoryPostProcessor接口的调用

BeanFactoryPostProcessor接口的继承关系如下,我们刚刚讲过的BeanDefinitionRegistryPostProcessor接口就继承了该接口,还有很多实现类,都是完成对bean的修改

BeanFactoryPostProcessor接口主要是完成对

调用流程
  1. 获取BeanFactoryPostProcessor的BeanName

获取实现了BeanFactoryPostProcessor接口的所有类的BeanDefinition对象的beanName

1
2
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
  1. 对实现了PriorityOrdered接口,Ordered接口的的BeanFactoryPostProcessor实现类排序
  2. 完成BeanFactoryPostProcessor的调用,方法是invokeBeanFactoryPostProcessors
invokeBeanFactoryPostProcessors

完成对BeanFactoryPostProcessor方法的调用,进行BeanDefinition的注册

这是一个扩展点,如果我需要使用java代码注册bean到spring,就可以实现该接口进行扩展

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* Invoke the given BeanFactoryPostProcessor beans.
* <p>
* 调用BeanFactoryPostProcessor的postProcessBeanFactory方法同样可以完成BeanDefinition的新增和修改
*/
private static void invokeBeanFactoryPostProcessors(
Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
//遍历调用BeanFactoryPostProcessor
for (BeanFactoryPostProcessor postProcessor : postProcessors) {
//完成调用过程
postProcessor.postProcessBeanFactory(beanFactory);
}
}
postProcessBeanFactory

调用具体实现了的postProcessBeanFactory接口完成BeanDefinition的注册

子类有很多实现我们就我们把最常用的讲解一下

ConfigurationClassPostProcessor

这个类我们在在后面的《Configuration注解的支持》会详细讲到我们先看下postProcessBeanFactory实现类

完成对@Configuration注解的解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* 完成对@Configuration注解的解析
*/
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
int factoryId = System.identityHashCode(beanFactory);
if (this.factoriesPostProcessed.contains(factoryId)) {
throw new IllegalStateException(
"postProcessBeanFactory already called on this post-processor against " + beanFactory);
}
this.factoriesPostProcessed.add(factoryId);
if (!this.registriesPostProcessed.contains(factoryId)) {
//处理已经注册的BeanDefinition
processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
}
enhanceConfigurationClasses(beanFactory);
//将beanPostProcessor添加到beanFactory
beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
}
小结
  1. 方法会检查factoryId是否已经执行过了,如果执行过了会报错的
  2. 如果没有执行过向factoriesPostProcessed添加factoryId
  3. 调用processConfigBeanDefinitions进行@Configuration注解的解析,详细流程参考《Configuration注解的支持》
  4. 将beanPostProcessor添加到beanFactory
addBeanPostProcessor

来到AbstractBeanFactory类

将beanPostProcessor添加到beanFactory

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* 实现beanPostProcessor的注册
*/
@Override
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
// Remove from old position, if any
this.beanPostProcessors.remove(beanPostProcessor);
// Track whether it is instantiation/destruction aware
//是否支持实例化InstantiationAwareBeanPostProcessor
if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
this.hasInstantiationAwareBeanPostProcessors = true;
}
if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
this.hasDestructionAwareBeanPostProcessors = true;
}
//将beanPostProcessor添加到beanPostProcessors
// Add to end of list
this.beanPostProcessors.add(beanPostProcessor);
}
小结

​ 1. 检查beanPostProcessor是否实现了InstantiationAwareBeanPostProcessor,如果实现了就将hasInstantiationAwareBeanPostProcessors设置为true,很重要,后面实例化会用到

 2. 将beanPostProcessor添加到beanPostProcessors,后面实例化会用到

BeanFactoryPostProcessor扩展

自定义扩展

实现BeanDefinitionRegistryPostProcessor,因为BeanDefinitionRegistryPostProcessor实现了BeanFactoryPostProcessor接口,重写两个方法实现手动注册BeanDefinition

Spring配置文件
1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

<context:component-scan base-package="com.test"/>
</beans>
手动注册的类

这个类是一个简单的UserDao我们做的方法是调用BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry接口完成UserDao的注册,并设置dialect属性,调用BeanPostProcessor接口的postProcessBeanFactory完成对pingSql属性的修改

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
public class UserDao {
/**
* 数据库类型
*/
private String dialect;
/**
* 数据库检测的语句
*/
private String pingSql;

public String getDialect() {
return dialect;
}

public void setDialect(String dialect) {
this.dialect = dialect;
}

public String getPingSql() {
return pingSql;
}

public void setPingSql(String pingSql) {
this.pingSql = pingSql;
}

@Override
public String toString() {
return "UserDao{" +
"dialect='" + dialect + '\'' +
", pingSql='" + pingSql + '\'' +
'}';
}
}

自定义PostProcessor
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
/**
* 自定义PostProcessor
*/
@Component
public class CustomPostProcessor implements BeanDefinitionRegistryPostProcessor {
/**
* 注册BeanDefinition
*
* @param registry
* @throws BeansException
*/
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
//创建GenericBeanDefinition
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
//设置BeanClass
beanDefinition.setBeanClass(UserDao.class);
//获取MutablePropertyValues
MutablePropertyValues mutablePropertyValues = beanDefinition.getPropertyValues();
//添加dialect的属性
mutablePropertyValues.add("dialect", "MYSQL");
//完成beanDefinition的中粗的
registry.registerBeanDefinition("userDao", beanDefinition);
System.out.println("完成BeanDefinition的注册");
}

/**
* 修改BeanDefinition
*
* @param beanFactory
* @throws BeansException
*/
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
String pingSql = "select 1 ";
//获取BeanDefinition
BeanDefinition beanDefinition = beanFactory.getBeanDefinition("userDao");
if (null != beanDefinition) {
//获取MutablePropertyValues
MutablePropertyValues mutablePropertyValues = beanDefinition.getPropertyValues();
String dialect = String.valueOf(mutablePropertyValues.get("dialect"));
if (dialect.equalsIgnoreCase("MYSQL")) {
//添加pingSql的属性
mutablePropertyValues.add("pingSql", pingSql);
}
}
System.out.println("完成BeanDefinition的修改");
}
}
测试类
1
2
3
4
5
6
7
8
9
public class SpringTest {
public static void main(String[] args) {
//创建Spring的上下文
ApplicationContext context = new ClassPathXmlApplicationContext("Spring.xml");
//获取Bean对象
UserDao userDao = (UserDao) context.getBean("userDao");
System.out.println(userDao);
}
}
输出
1
2
3
完成BeanDefinition的注册
完成BeanDefinition的修改
UserDao{dialect='MYSQL', pingSql='select 1 '}

MyBatis的扩展

我们通常在使用 Mybatis + Spring 时,经常用到的 org.mybatis.spring.mapper.MapperScannerConfigurer 就是一个BeanDefinitionRegistryPostProcessor。MapperScannerConfigurer 在 postProcessBeanDefinitionRegistry 方法中进行了一些操作,主要是:扫描 basePackage 指定的目录,将该目录下的类(通常是 DAO/MAPPER 接口)封装成 BeanDefinition 并加载到 BeanFactory 中。因此,我们可以看到我们项目中的 DAO(MAPPER)接口,通常都没有使用注解或 XML 的方式注册到 Spring 容器,但是我们还是可以在 Service 服务中,使用 @Autowire 注解来将其注入到 Service 中,就是因为这个原因。

1
2
3
4
5
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--basePackage指定要扫描的包,在此包之下的映射器都会被搜索到。可指定多个包,包与包之间用逗号或分号分隔-->
<property name="basePackage" value="com.test.mapper"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
MapperScannerConfigurer扩展
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//实现了BeanDefinitionRegistryPostProcessor接口可以注册BeanDefinition
public class MapperScannerConfigurer implements BeanDefinitionRegistryPostProcessor, InitializingBean, ApplicationContextAware, BeanNameAware {
....

public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
if (this.processPropertyPlaceHolders) {
this.processPropertyPlaceHolders();
}

ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry);
scanner.setAddToConfig(this.addToConfig);
scanner.setAnnotationClass(this.annotationClass);
scanner.setMarkerInterface(this.markerInterface);
scanner.setSqlSessionFactory(this.sqlSessionFactory);
scanner.setSqlSessionTemplate(this.sqlSessionTemplate);
scanner.setSqlSessionFactoryBeanName(this.sqlSessionFactoryBeanName);
scanner.setSqlSessionTemplateBeanName(this.sqlSessionTemplateBeanName);
scanner.setResourceLoader(this.applicationContext);
scanner.setBeanNameGenerator(this.nameGenerator);
scanner.registerFilters();
scanner.scan(StringUtils.tokenizeToStringArray(this.basePackage, ",; \t\n"));
}
....
}

总结

在调用invokeBeanFactoryPostProcessors接口的时候会涉及到两个接口

  • BeanFactoryPostProcessor
  • BeanDefinitionRegistryPostProcessor

BeanFactoryPostProcessor:是在BeanDefinition注册完成后进行进行对BeanDefinition进行修改的接口,有许多的实现类。

BeanDefinitionRegistryPostProcessor:实现了BeanFactoryPostProcessor接口,是对BeanFactoryPostProcessor接口的扩展,BeanFactoryPostProcessor只能对BeanDefinition进行修改,但是BeanDefinitionRegistryPostProcessor接口可以完成BeanDefinition的注册,手工创建的类可以交给spring进行管理。

invokeBeanFactoryPostProcessors 总结

  1. 整个 invokeBeanFactoryPostProcessors 方法围绕两个接口,BeanDefinitionRegistryPostProcessor 和 BeanFactoryPostProcessor,其中 BeanDefinitionRegistryPostProcessor 继承了 BeanFactoryPostProcessor 。BeanDefinitionRegistryPostProcessor 主要用来在常规 BeanFactoryPostProcessor 检测开始之前注册其他 Bean 定义,说的简单点,就是 BeanDefinitionRegistryPostProcessor 具有更高的优先级,执行顺序在 BeanFactoryPostProcessor 之前。

  2. 整个 invokeBeanFactoryPostProcessors 方法操作了 3 种 bean 对象:

  • 入参 beanFactoryPostProcessors:这个我们在代码块1中解析过,拿的是 AbstractApplicationContext 类的 beanFactoryPostProcessors 属性值,也就是在之前已经添加到 beanFactoryPostProcessors 中的 BeanFactoryPostProcessor。
  • BeanDefinitionRegistryPostProcessor 接口实现类:实现了 BeanDefinitionRegistryPostProcessor 接口,并且注册到 Spring IoC容器中。
  • 常规 BeanFactoryPostProcessor 接口实现类:实现了 BeanFactoryPostProcessor 接口,并且注册到 Spring IoC容器中。
  1. 操作3种 bean 对象具体指的是调用它们重写的方法,调用实现方法时会遵循以下的优先级:
  • 第一优先级:入参 beanFactoryPostProcessors 中的 BeanDefinitionRegistryPostProcessor, 调用 postProcessBeanDefinitionRegistry 方法(2.1.1)。
  • 第二优先级:BeanDefinitionRegistryPostProcessor 接口实现类,并且实现了 PriorityOrdered 接口,调用 postProcessBeanDefinitionRegistry 方法(3.8)。
  • 第三优先级:BeanDefinitionRegistryPostProcessor 接口实现类,并且实现了 Ordered 接口,调用 postProcessBeanDefinitionRegistry 方法(4.2)。
  • 第四优先级:除去第二优先级和第三优先级,剩余的 BeanDefinitionRegistryPostProcessor 接口实现类,调用 postProcessBeanDefinitionRegistry 方法(5.4)。
  • 第五优先级:所有 BeanDefinitionRegistryPostProcessor 接口实现类,调用 postProcessBeanFactory 方法(6)。
  • 第六优先级:入参 beanFactoryPostProcessors 中的常规 BeanFactoryPostProcessor,调用 postProcessBeanFactory 方法(7)。
  • 第七优先级:常规 BeanFactoryPostProcessor 接口实现类,并且实现了 PriorityOrdered 接口,调用 postProcessBeanFactory 方法(9.2)。
  • 第八优先级:常规 BeanFactoryPostProcessor 接口实现类,并且实现了 Ordered 接口,调用 postProcessBeanFactory 方法(10.3)。
  • 第九优先级:除去第七优先级和第八优先级,剩余的常规 BeanFactoryPostProcessor 接口的实现类,调用 postProcessBeanFactory 方法(11.2)。
  1. 本文还引入了两个用于排序的重要接口:PriorityOrdered 和 Ordered,其中 PriorityOrdered 继承了 Ordered,并且 PriorityOrdered 的优先级要高于 Ordered,这跟 BeanDefinitionRegistryPostProcessor 继承 BeanFactoryPostProcessor 有点类似。实现 Ordered 接口需要重写 getOrder 方法,返回一个用于排序的 order 值,order 值的范围为 Integer.MIN_VALUE ~ Integer.MAX_VALUE,order 值越小优先级越高,Integer.MIN_VALUE 拥有最高优先级,而 Integer.MAX_VALUE 则对应的拥有最低优先级。

  2. 常见的 Java EE 相关的框架或者中间件,经常使用 BeanFactoryPostProcessor 来进行扩展,例如上面的 Mybatis,因此了解 BeanFactoryPostProcessor 的原理会对之后理解其他中间件的原理有帮助。

评论