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

SpringIOC-注册BeanPostProcessors

前言

​ 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 方法。

registerBeanPostProcessors

入口方法是registerBeanPostProcessors,主要完成BeanPostProcessors提前实例化以及注册

1
2
3
4
5
6
7
/**
* 把实现BeanPostProcessor接口注册到beanFactory
*/
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// 1.注册BeanPostProcessor
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}

registerBeanPostProcessors

来到PostProcessorRegistrationDelegate类

把实现了BeanPostProcessor接口的类实例化,并且加入到BeanFactory中

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
/**
* 完成注册BeanPostProcessor
*
* @param beanFactory
* @param applicationContext
*/
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
//获取所有的BeanPostProcessor的BeanDefinition的name
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
// BeanPostProcessor的目标计数
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
// 2.添加BeanPostProcessorChecker(主要用于记录信息)到beanFactory中
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
// 3.定义不同的变量用于区分: 实现PriorityOrdered接口的BeanPostProcessor、实现Ordered接口的BeanPostProcessor、普通BeanPostProcessor
// 3.1 priorityOrderedPostProcessors: 用于存放实现PriorityOrdered接口的BeanPostProcessor
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
// 3.2 internalPostProcessors: 用于存放Spring内部的BeanPostProcessor
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
// 3.3 orderedPostProcessorNames: 用于存放实现Ordered接口的BeanPostProcessor的beanName
List<String> orderedPostProcessorNames = new ArrayList<>();
// 3.4 nonOrderedPostProcessorNames: 用于存放普通BeanPostProcessor的beanName
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
//提前实例化BeanPostProcessor类型的bean,然后bean进行排序
// 4.遍历postProcessorNames, 将BeanPostProcessors按3.1 - 3.4定义的变量区分开
for (String ppName : postProcessorNames) {
// 4.1 如果ppName对应的Bean实例实现了PriorityOrdered接口, 则拿到ppName对应的Bean实例并添加到priorityOrderedPostProcessors
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//getBean是实例化方法,后面我们在讲bean实例化过程是会着重讲到
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
//添加到priorityOrderedPostProcessors集合
priorityOrderedPostProcessors.add(pp);

//判断类型是否是MergedBeanDefinitionPostProcessor,如果是则代码是内部使用的
if (pp instanceof MergedBeanDefinitionPostProcessor) {
// 4.2 如果ppName对应的Bean实例也实现了MergedBeanDefinitionPostProcessor接口,
// 则将ppName对应的Bean实例添加到internalPostProcessors
internalPostProcessors.add(pp);
}
} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
// 4.3 如果ppName对应的Bean实例没有实现PriorityOrdered接口, 但是实现了Ordered接口, 则将ppName添加到orderedPostProcessorNames
orderedPostProcessorNames.add(ppName);
} else {
// 4.4 否则, 将ppName添加到nonOrderedPostProcessorNames
nonOrderedPostProcessorNames.add(ppName);
}
}


// First, register the BeanPostProcessors that implement PriorityOrdered.
// 5.首先, 注册实现PriorityOrdered接口的BeanPostProcessors
// 5.1 对priorityOrderedPostProcessors进行排序
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);

// 5.2 注册priorityOrderedPostProcessors
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

// Next, register the BeanPostProcessors that implement Ordered.
// 6.接下来, 注册实现Ordered接口的BeanPostProcessors
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
//遍历实现了Ordered接口的orderedPostProcessorNames
for (String ppName : orderedPostProcessorNames) {
// 6.1 拿到ppName对应的BeanPostProcessor实例对象
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
// 6.2 将ppName对应的BeanPostProcessor实例对象添加到orderedPostProcessors, 准备执行注册
orderedPostProcessors.add(pp);
//判断类型是否是MergedBeanDefinitionPostProcessor,如果是则代码是内部使用的
if (pp instanceof MergedBeanDefinitionPostProcessor) {
// 6.3 如果ppName对应的Bean实例也实现了MergedBeanDefinitionPostProcessor接口,
// 则将ppName对应的Bean实例添加到internalPostProcessors
internalPostProcessors.add(pp);
}
}
// 6.4 对orderedPostProcessors进行排序
sortPostProcessors(orderedPostProcessors, beanFactory);
// 6.5 注册orderedPostProcessors
registerBeanPostProcessors(beanFactory, orderedPostProcessors);

//完成没有实现任何排序接口的BeanPostProcessor的注册
// 7.注册所有常规的BeanPostProcessors(过程与6类似)
// Now, register all regular BeanPostProcessors.
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
//遍历没有实现排序接口的nonOrderedPostProcessorNames
for (String ppName : nonOrderedPostProcessorNames) {
//实例化BeanPostProcessor
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
//添加到nonOrderedPostProcessors
nonOrderedPostProcessors.add(pp);
//判断类型是否是MergedBeanDefinitionPostProcessor,如果是则代码是内部使用的
if (pp instanceof MergedBeanDefinitionPostProcessor) {
//添加到internalPostProcessors
internalPostProcessors.add(pp);
}
}
//注册到BeanFactory中
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

// 8.最后, 重新注册所有内部BeanPostProcessors(相当于内部的BeanPostProcessor会被移到处理器链的末尾)
// 8.1 对internalPostProcessors进行排序
// Finally, re-register all internal BeanPostProcessors.
sortPostProcessors(internalPostProcessors, beanFactory);
// 8.2注册internalPostProcessors
registerBeanPostProcessors(beanFactory, internalPostProcessors);

// 9.重新注册ApplicationListenerDetector(跟8类似,主要是为了移动到处理器链的末尾)
// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
registerBeanPostProcessors
1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* Register the given BeanPostProcessor beans.
* 将BeanPostProcessor注册到beanFactory
*/
private static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
//1. 遍历所有的BeanPostProcessor
for (BeanPostProcessor postProcessor : postProcessors) {
// 2.将PostProcessor添加到BeanFactory中的beanPostProcessors缓存
beanFactory.addBeanPostProcessor(postProcessor);
}
}

beanFactory.addBeanPostProcessor

将PostProcessor添加到BeanFactory中的beanPostProcessors缓存

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
/**
* 实现beanPostProcessor的注册
*
* @param beanPostProcessor
*/
@Override
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
// Remove from old position, if any
// 1.如果beanPostProcessor已经存在则移除(可以起到排序的效果,beanPostProcessor可能本来在前面,移除再添加,则变到最后面)
this.beanPostProcessors.remove(beanPostProcessor);
// Track whether it is instantiation/destruction aware
//是否支持实例化InstantiationAwareBeanPostProcessor
if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
// 2.如果beanPostProcessor是InstantiationAwareBeanPostProcessor, 则将hasInstantiationAwareBeanPostProcessors设置为true,
// 该变量用于指示beanFactory是否已注册过InstantiationAwareBeanPostProcessors
this.hasInstantiationAwareBeanPostProcessors = true;
}
//是否支持实例化DestructionAwareBeanPostProcessor
if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
// 3.如果beanPostProcessor是DestructionAwareBeanPostProcessor, 则将hasInstantiationAwareBeanPostProcessors设置为true,
// 该变量用于指示beanFactory是否已注册过DestructionAwareBeanPostProcessor
this.hasDestructionAwareBeanPostProcessors = true;
}
// 2.将beanPostProcessor添加到beanPostProcessors缓存
// Add to end of list
this.beanPostProcessors.add(beanPostProcessor);
}

​ 该方法作用就是将 BeanPostProcessor 添加到 beanPostProcessors 缓存,这边的先移除再添加,主要是起一个排序的作用。而 hasInstantiationAwareBeanPostProcessors 和 hasDestructionAwareBeanPostProcessors 变量用于指示 beanFactory 是否已注册过 InstantiationAwareBeanPostProcessors 和 DestructionAwareBeanPostProcessor,在之后的 IoC 创建过程会用到这两个变量,这边先有个印象。

BeanPostProcessors接口

Spring提供了一个BeanPostProcessor接口,这个接口的作用在于对于新构造的实例可以做一些自定义的修改。比如如何构造、属性值的修改、构造器的选择。

如果想改变Spring容器中bean的一些属性或者行为,可以通过自定义类实现BeanPostProcessor接口实现。

BeanPostProcessor的定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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总结

  1. postProcessBeforeInitialization方法的作用在于目标对象实例化之后,初始化之前调用,默认返回原始对象,也可以返回一个包装实例;
    如果返回null,接下来的BeanPostProcessors都不会执行
  2. postProcessAfterInitialization方法的作用在于目标对象实例化之后,初始化之后调用,默认返回原始对象,也可以返回一个包装实例;
    如果返回null,接下来的BeanPostProcessors都不会执行
  3. 初始化(Initialization):表示生成对象,未设置属性;初始化之前表示bean的初始化回调之前,如InitializingBean接口的afterPropertiesSet方法或者自定义的init-method方法

常用的接口

InstantiationAwareBeanPostProcessor

InstantiationAwareBeanPostProcessor接口继承自BeanPostProcessor接口,定义了4个方法

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
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {


@Nullable
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}


default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return true;
}


@Nullable
default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
throws BeansException {

return null;
}

@Deprecated
@Nullable
default PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {

return pvs;
}
}

小结
  1. postProcessBeforeInstantiation方法在目标对象实例化之前调用,可以返回一个代理对象来代替目标对象本身;如果返回非null对象,则除了调用postProcessAfterInitialization方法外,其他bean的构造过程都不再调用;
  2. postProcessAfterInstantiation方法在对象实例化之后,属性设置之前调用;如果返回值是true,目标bean的属性会被populate,返回false则忽略populate过程;
  3. postProcessPropertyValues方法在属性被设置到目标实例之前调用,可以修改属性的设置,PropertyValues pvs表示参数值,PropertyDescriptor[] pds表示目标bean 的属性描述信息,返回值PropertyValues,可以用一个全新的PropertyValues来替代原来的pvs,如果返回null,将忽略属性设置过程;
SmartInstantiationAwareBeanPostProcessor

SmartInstantiationAwareBeanPostProcessor接口继承InstantiationAwareBeanPostProcessor接口,定义了3个方法,作用是在于目标对象的实例化过程中需要处理的事情。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {

@Nullable
default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
return null;
}


@Nullable
default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)
throws BeansException {

return null;
}

default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
return bean;
}

}

小结
  1. predictBeanType方法预测Bean的类型,返回预测成功的Class类型,默认或如果不能预测返回null

  2. determineCandidateConstructors方法用于选择合适的构造器,如果类有多个构造器,可以实现这个方法选择合适的构造器并用于实例化对象;该方法在postProcessBeforeInstantiation方法和postProcessAfterInstantiation方法之间调用,如果postProcessBeforeInstantiation方法返回了一个新的实例代替了原本该生成的实例,那么该方法会被忽略;

  3. getEarlyBeanReference方法用于解决循环引用问题。比如ReferenceA实例内部有ReferenceB的引用,ReferenceB实例内部有ReferenceA的引用。首先先实例化ReferenceA,实例化完成之后提前把这个bean暴露在ObjectFactory中,然后populate属性,这个时候发现需要ReferenceB。然后去实例化ReferenceB,在实例化ReferenceB的时候它需要ReferenceA的实例才能继续,这个时候就会去ObjectFactory中找出了ReferenceA实例,ReferenceB顺利实例化。ReferenceB实例化之后,ReferenceA的populate属性过程也成功完成,注入了ReferenceB实例。提前把这个bean暴露在ObjectFactory中,这个ObjectFactory获取的实例就是通过getEarlyBeanReference方法得到的;

DestructionAwareBeanPostProcessor
1
2
3
4
5
6
7
8
9
10
public interface DestructionAwareBeanPostProcessor extends BeanPostProcessor {

void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException;

default boolean requiresDestruction(Object bean) {
return true;
}

}

小结
  1. postProcessBeforeDestruction方法在目标bean被销毁之前调用,该回调适用于单例bean的使用;
  2. 判断目标bean是否需要回调postProcessBeforeDestruction方法;

总结

​ Spring内部对象bean的生命周期管理有一套完成的体系,并遵循了设计模式中的开闭原则(开放扩展,关闭修改),如果想修改bean的相关信息,可以通过Spring提供的扩展点,如BeanPostProcessor接口去处理,这样做的好处是不需要关心Spring内部处理逻辑,扩展方便。

BeanPostProcessor扩展

自定义实现

创建BeanPostProcessor的实现类
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
@Component
public class CustomBeanPostProcessor implements BeanPostProcessor {
//实例化之后执行
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("bean实例化完成:" + beanName);
//修改实例化后的bean
if (bean instanceof UserDao) {
UserDao userDao = (UserDao) bean;
userDao.setPingSql("postProcessAfterInitialization");
}
return bean;
}


//实例化前执行
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("开始实例化:" + beanName);
//修改实例化后的bean
if (bean instanceof UserDao) {
UserDao userDao = (UserDao) bean;
userDao.setPingSql("postProcessBeforeInitialization");
}
return bean;
}
}
测试类
1
2
3
4
5
6
7
8
9
10
public class SpringTest {
public static void main(String[] args) {
//创建Spring的上下文
ApplicationContext context = new ClassPathXmlApplicationContext("Spring.xml");
//获取Bean对象
System.out.println("开始调用getBean");
UserDao userDao = (UserDao) context.getBean("userDao");
System.out.println(userDao);
}
}
打印信息
1
2
3
4
开始实例化:userDao
bean实例化完成:userDao
开始调用getBean
UserDao{dialect='MYSQL', pingSql='yyyyyyyyyyyyy'}

评论