二十八、IOC之BeanPostProcessor

IOC之BeanPostProcessor

BeanPostProcessor接口

除了Aware这个扩展点,还有BeanPostProcessor,BeanPostProcessor 的作用:在 Bean 完成实例化后,如果我们需要对其进行一些配置、增加一些自己的处理逻辑,那么请使用 BeanPostProcessor。

BeanPostProcessor实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class TestBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("Bean[" + beanName + "]开始初始化");
return bean;
}

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("Bean[" + beanName + "]完成初始化");
return bean;
}

public void display(){
System.out.println("Hello BeanPostProcessor...");
}
}
1
2
3
4
5
6
7
<?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="testBeanPostProcessor" class="com.jievhaha.TestBeanPostProcessor"/>
</beans>
1
2
3
4
5
6
7
8
9
10
public class MyApplication {
public static void main(String[] args) {
ClassPathResource resource = new ClassPathResource("applicationContext.xml");
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(resource);
TestBeanPostProcessor testBeanPostProcessor = (TestBeanPostProcessor) factory.getBean("testBeanPostProcessor");
testBeanPostProcessor.display();
}
}

输出结果为:

1
Hello BeanPostProcessor...

并没有执行前置、后置处理器。

AbstractAutowireCapableBeanFactory.initializeBean()中:

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
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) { // 安全模式
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
// <1> 激活 Aware 方法,对特殊的 bean 处理:Aware、BeanClassLoaderAware、BeanFactoryAware
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
// <1> 激活 Aware 方法,对特殊的 bean 处理:Aware、BeanClassLoaderAware、BeanFactoryAware
invokeAwareMethods(beanName, bean);
}
// <2> 后置处理器,before
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}

// <3> 激活用户自定义的 init 方法
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
// <2> 后置处理器,after
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}

return wrappedBean;
}

@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException {

Object result = existingBean;
// 遍历 BeanPostProcessor 数组
for (BeanPostProcessor processor : getBeanPostProcessors()) {
// 处理
Object current = processor.postProcessBeforeInitialization(result, beanName);
// 返回空,则返回 result
if (current == null) {
return result;
}
// 修改 result
result = current;
}
return result;
}
1
2
3
4
5
6
// AbstractBeanFactory.java
public List<BeanPostProcessor> getBeanPostProcessors() {
return this.beanPostProcessors;
}

private final List<BeanPostProcessor> beanPostProcessors = new BeanPostProcessorCacheAwareList();

断点中可以查看到getBeanPostProcessors()size为0。

所以要想执行前置处理器就要保证该List不为空,那就要有this.beanPostProcessors.add()的过程:

1
2
3
4
5
6
7
// AbstractBeanFactory.java
@Override
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
this.beanPostProcessors.remove(beanPostProcessor);
this.beanPostProcessors.add(beanPostProcessor);
}

该方法是由 AbstractBeanFactory 的父类 org.springframework.beans.factory.config.ConfigurableBeanFactory 接口定义,它的核心意思就是将指定 BeanPostProcessor 注册到该 BeanFactory 创建的 bean 中,同时它是按照插入的顺序进行注册的,完全忽略 Ordered 接口所表达任何排序语义(在 BeanPostProcessor 中我们提供一个 Ordered 顺序)。

所以要可以执行前后置处理器,只需增加如下步骤:

1
2
3
4
5
6
7
8
9
10
11
12
TestBeanPostProcessor test = new TestBeanPostProcessor();
factory.addBeanPostProcesssor(test)。


ClassPathResource resource = new ClassPathResource("applicationContext.xml");
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
TestBeanPostProcessor beanPostProcessor = new TestBeanPostProcessor();
factory.addBeanPostProcessor(beanPostProcessor);
reader.loadBeanDefinitions(resource);
TestBeanPostProcessor testBeanPostProcessor = (TestBeanPostProcessor) factory.getBean("testBeanPostProcessor");
testBeanPostProcessor.display();

这样,使用该factory创建任何Bean都会执行前后置处理器,ApplicationContext方法不需手动注册,会自动检测所有BeanPostProcessor然后进行自动注册(都已测试)。

总结:一般普通的 BeanFactory 是不支持自动注册 BeanPostProcessor 的,需要我们手动调用 addBeanPostProcessor(BeanPostProcessor beanPostProcessor) 方法进行注册。注册后的 BeanPostProcessor 适用于所有该 BeanFactory 创建的 bean,但是 ApplicationContext 可以在其 bean 定义中自动检测所有的 BeanPostProcessor 并自动完成注册,同时将他们应用到随后创建的任何 Bean 中

BeanPostProcessor基本原理

BeanPostProcessor接口:

1
2
3
4
5
6
7
8
9
10
11
12
public interface BeanPostProcessor {
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}

@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}

}

BeanPostProcessor 可以理解为是 Spring 的一个工厂钩子(其实 Spring 提供一系列的钩子,如 Aware 、InitializingBean、DisposableBean),它是 Spring 提供的对象实例化阶段强有力的扩展点,允许 Spring 在实例化 bean 阶段对其进行定制化修改,比较常见的使用场景是处理标记接口实现类或者为当前对象提供代理实现(例如 AOP)。

postProcessBeforeInitialization(Object bean, String beanName)postProcessAfterInitialization(Object bean, String beanName) 两个方法,都接收一个 Object 类型的 bean ,一个 String 类型的 beanName ,其中 bean 是已经实例化了的 instanceBean ,能拿到这个你是不是可以对它为所欲为了? 这两个方法是初始化 bean 的前后置处理器,他们应用 invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd) 方法的前后。

前后置处理器

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
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) { // 安全模式
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
// <1> 激活 Aware 方法,对特殊的 bean 处理:Aware、BeanClassLoaderAware、BeanFactoryAware
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
// <1> 激活 Aware 方法,对特殊的 bean 处理:Aware、BeanClassLoaderAware、BeanFactoryAware
invokeAwareMethods(beanName, bean);
}
// <2> 后置处理器,before
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}

// <3> 激活用户自定义的 init 方法
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
// <2> 后置处理器,after
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}

return wrappedBean;
}

@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException {

Object result = existingBean;
// 遍历 BeanPostProcessor 数组
for (BeanPostProcessor processor : getBeanPostProcessors()) {
// 处理
Object current = processor.postProcessBeforeInitialization(result, beanName);
// 返回空,则返回 result
if (current == null) {
return result;
}
// 修改 result
result = current;
}
return result;
}

@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {

Object result = existingBean;
// 遍历 BeanPostProcessor
for (BeanPostProcessor processor : getBeanPostProcessors()) {
// 处理
Object current = processor.postProcessAfterInitialization(result, beanName);
// 返回空,则返回 result
if (current == null) {
return result;
}
result = current;
}
return result;
}
自动检测并注册

getBeanPostProcessors() 方法,返回的是 beanPostProcessors 集合,该集合里面存放就是我们自定义的 BeanPostProcessor ,如果该集合中存在元素则调用相应的方法,否则就直接返回 bean 了。这也是为什么使用 BeanFactory 容器是无法输出自定义 BeanPostProcessor 里面的内容,因为在 BeanFactory.getBean(...) 方法的过程中根本就没有将我们自定义的 BeanPostProcessor 注入进来,所以要想 BeanFactory 容器 的 BeanPostProcessor 生效我们必须手动调用 addBeanPostProcessor(BeanPostProcessor beanPostProcessor) 方法,将定义的 BeanPostProcessor 注册到相应的 BeanFactory 中。但是 ApplicationContext 不需要手动,因为 ApplicationContext 会自动检测并完成注册

ApplicationContext 实现自动注册的原因,在于我们构造一个 ApplicationContext 实例对象的时候会调用 AbstractApplicationContext.registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) 方法,将检测到的 BeanPostProcessor 注入到 ApplicationContext 容器中,同时应用到该容器创建的 bean 中。

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
// AbstractApplicationContext.java

/**
* 实例化并调用已经注入的 BeanPostProcessor
* 必须在应用中 bean 实例化之前调用
*/
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}

// PostProcessorRegistrationDelegate.java
public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// 获取所有的 BeanPostProcessor 的 beanName
// 这些 beanName 都已经全部加载到容器中去,但是没有实例化
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

// 记录所有的beanProcessor数量
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
// 注册 BeanPostProcessorChecker,它主要是用于在 BeanPostProcessor 实例化期间记录日志
// 当 Spring 中高配置的后置处理器还没有注册就已经开始了 bean 的实例化过程,这个时候便会打印 BeanPostProcessorChecker 中的内容
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

// PriorityOrdered 保证顺序
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
// 使用 Ordered 保证顺序
List<String> orderedPostProcessorNames = new ArrayList<>();
// 没有顺序
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 调用 getBean 获取 bean 实例对象
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
// 有序 Ordered
orderedPostProcessorNames.add(ppName);
}
else {
// 无序
nonOrderedPostProcessorNames.add(ppName);
}
}

// 第一步,注册所有实现了 PriorityOrdered 的 BeanPostProcessor
// 先排序
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 后注册
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

// 第二步,注册所有实现了 Ordered 的 BeanPostProcessor
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);

// 第三步注册所有无序的 BeanPostProcessor
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 类型的 BeanPostProcessor
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);

// 加入ApplicationListenerDetector(探测器)
// 重新注册 BeanPostProcessor 以检测内部 bean,因为 ApplicationListeners 将其移动到处理器链的末尾
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

逻辑:

  • 首先 beanFactory 获取注册到该 BeanFactory 中所有 BeanPostProcessor 类型的 beanName 数组,其实就是找所有实现了 BeanPostProcessor 接口的 bean ,然后迭代这些 bean ,将其按照 PriorityOrdered、Ordered、无序的顺序,添加至相应的 List 集合中,最后依次调用 sortPostProcessors(List postProcessors, ConfigurableListableBeanFactory beanFactory) 方法来进行排序处理、 registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, List postProcessors) 方法来完成注册。
  • 排序很简单,如果 beanFactory 为 DefaultListableBeanFactory ,则返回 BeanFactory 所依赖的比较器,否则反正默认的比较器(OrderComparator),然后调用 Listsort(Comparator c) 方法即可。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// PostProcessorRegistrationDelegate.java
private static void sortPostProcessors(List<?> postProcessors, ConfigurableListableBeanFactory beanFactory) {
// Nothing to sort?
if (postProcessors.size() <= 1) {
return;
}
// 获得 Comparator 对象
Comparator<Object> comparatorToUse = null;
if (beanFactory instanceof DefaultListableBeanFactory) {// 依赖的 Comparator 对象
comparatorToUse = ((DefaultListableBeanFactory) beanFactory).getDependencyComparator();
}
if (comparatorToUse == null) {// 默认 Comparator 对象
comparatorToUse = OrderComparator.INSTANCE;
}
// 排序
postProcessors.sort(comparatorToUse);
}
  • 注册同样是调用 AbstractBeanFactory.addBeanPostProcessor(BeanPostProcessor beanPostProcessor) 方法完成注册。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {

// 如果是AbstractBeanFactory,直接全部注册
if (beanFactory instanceof AbstractBeanFactory) {
// Bulk addition is more efficient against our CopyOnWriteArrayList there
((AbstractBeanFactory) beanFactory).addBeanPostProcessors(postProcessors);
}
else {
// 遍历 BeanPostProcessor 数组,注册
for (BeanPostProcessor postProcessor : postProcessors) {
beanFactory.addBeanPostProcessor(postProcessor);
}
}
}

总结

  1. BeanPostProcessor 的作用域是容器级别的,它只和所在的容器相关 ,当 BeanPostProcessor 完成注册后,它会应用于所有跟它在同一个容器内的 bean 。
  2. BeanFactory 和 ApplicationContext 对 BeanPostProcessor 的处理不同,ApplicationContext 会自动检测所有实现了 BeanPostProcessor 接口的 bean,并完成注册,但是使用 BeanFactory 容器时则需要手动调用 AbstractBeanFactory.addBeanPostProcessor(BeanPostProcessor beanPostProcessor) 方法来完成注册
  3. ApplicationContext 的 BeanPostProcessor 支持 Ordered,而 BeanFactory 的 BeanPostProcessor 是不支持的,原因在于ApplicationContext 会对 BeanPostProcessor 进行 Ordered 检测并完成排序,而 BeanFactory 中的 BeanPostProcessor 只跟注册的顺序有关。

二十八、IOC之BeanPostProcessor
http://www.muzili.ren/2022/06/11/IOC之BeanPostProcessor/
作者
jievhaha
发布于
2022年6月11日
许可协议