Spring扩展接口解析4--bean后置处理器BeanPostProcessor接口

本文内容纲要:

- 前言

- 1、BeanPostProcessor接口

- 2、后置处理器的使用

- 3、后置处理器的实现原理

- 3.1、初始化后置处理器

- 3.2、 添加后置处理器

- 4、BeanPostProcessor的子接口

- 4.1、InstantiationAwareBeanPostProcessor

- 4.2、MergedBeanDefinitionPostProcessor

- 4.3、SmartInstantiationAwareBeanPostProcessor

- 4.4、DestructionAwareBeanPostProcessor

- 5、Spring的核心后置处理器(*)

- 5.1、AutowiredAnnotationBeanPostProcessor(@Autowired注解处理器)

- 5.2、CommonAnnotationBeanPostProcessor(@Resource注解处理器)

- 5.3、ApplicationContextAwareProcessor(Aware子接口方法执行)

- 6、Extra(*)

前言

众所周知,Spring的核心思想为IOC和AOP,而AOP实际就是在对业务代码进行逻辑增强,以切面的形式将需要增强的代码加入到业务代码前后去执行。而处理业务代码的增强,在Bean的初始化过程中通用采用了AOP设计思想,来对bean进行功能增强。

比如Spring容器加载了bean之后,如果需要对所有的bean,或者某部分bean进行功能增强时,此时就可以采用一个叫做后置处理器的工具来对bean进行增强或扩展,Spring中的后置处理器也就是BeanPostProcessor接口。

1、BeanPostProcessor接口

BeanPostProcessor接口就是Spring后置处理器的顶级接口,该接口只有两个方法,一个是在bean执行初始化方法之前执行,一个是在bean执行初始化方法之后执行,源码如下:

1 public interface BeanPostProcessor {

2

3 /**

4 * bean执行初始化方法之前执行该方法

5 */

6 @Nullable

7 default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {

8 return bean;

9 }

10

11 /**

12 * bean执行初始化之后执行该方法

13 */

14 @Nullable

15 default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

16 return bean;

17 }

18 }

Spring容器加载bean的时候,会先创建bean,然后对bean进行属性注入,然后再执行bean的初始化方法,而后置处理器就是在bean执行初始化方法initializeBean方法中进行处理的,逻辑代码如下:

1 protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {

2

3 /**1.执行实现了Aware系列接口的方法*/

4 invokeAwareMethods(beanName, bean);

5

6 Object wrappedBean = bean;

7 /** 2.遍历执行所有后置处理器的初始化之前处理方法*/

8 if (mbd == null || !mbd.isSynthetic()) {

9 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);

10 }

11

12 /** 3.执行初始化方法*/

13 invokeInitMethods(beanName, wrappedBean, mbd);

14

15 /** 4.遍历执行所有后置处理器的初始化之后处理方法*/

16 if (mbd == null || !mbd.isSynthetic()) {

17 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);

18 }

19 return wrappedBean;

20 }

1 @Override

2 public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)

3 throws BeansException {

4

5 Object result = existingBean;

6 /** 遍历执行postProcessBeforeInitialization方法*/

7 for (BeanPostProcessor processor : getBeanPostProcessors()) {

8 Object current = processor.postProcessBeforeInitialization(result, beanName);

9 if (current == null) {

10 return result;

11 }

12 result = current;

13 }

14 return result;

15 }

16

17 @Override

18 public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)

19 throws BeansException {

20

21 Object result = existingBean;

22 /** 遍历执行postProcessAfterInitialization方法*/

23 for (BeanPostProcessor processor : getBeanPostProcessors()) {

24 Object current = processor.postProcessAfterInitialization(result, beanName);

25 if (current == null) {

26 return result;

27 }

28 result = current;

29 }

30 return result;

31 }

可以看出在bean执行初始化之前,会遍历所有后置处理器,执行后置处理器的postProcessBeforeInitialization方法,而在初始化之后会遍历所有后置处理器,执行postProcessorAfterInitialization方法。

2、后置处理器的使用

自定义后置处理器,作用是在bean初始化之前打印日志,bean初始化之后如果beanName是以xxxService命名的,则通过bean的Class重新创建一个bean对象,自定义后置处理器代码如下:

1 public class MyBeanPostProcessor implements BeanPostProcessor {

2

3 @Override

4 public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {

5 System.out.println("后置处理器 初始化方法之前执行");

6 return bean;

7 }

8

9 @Override

10 public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

11 System.out.println("后置处理器 初始化方法之后执行");

12 if(beanName.endsWith("Service")){

13 try {

14 System.out.println("通过类的newInstance方法创造对象");

15 Class c = bean.getClass();

16 bean = c.newInstance();

17 } catch (Exception e) {

18 e.printStackTrace();

19 }

20 }

21 return bean;

22 }

23

24 }

定义GoodsService类代码如下:

1 public class GoodsService {

2

3 private String orderCode;

4 private String goodsCode;

5

6 public GoodsService(){

7

8 }

9

10 public GoodsService(String goodsCode, String orderCode){

11 this.goodsCode = goodsCode;

12 this.orderCode = orderCode;

13 }

14

15 public void init(){

16 System.out.println("执行init方法");

17 }

18

19 public String getOrderCode() {

20 return orderCode;

21 }

22

23 public void setOrderCode(String orderCode) {

24 this.orderCode = orderCode;

25 }

26

27 public String getGoodsCode() {

28 return goodsCode;

29 }

30

31 public void setGoodsCode(String goodsCode) {

32 this.goodsCode = goodsCode;

33 }

34 }

application.xml添加bean和后置处理器的声明,代码如下:

1 <?xml version="1.0" encoding="UTF-8" ?>

2 <beans xmlns="http://www.springframework.org/schema/beans"

3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"

4 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

5

6

7

8 <bean id="goodsService" class="com.lucky.test.spring.demo.GoodsService" init-method="init">

9 <constructor-arg index="0" value="test_order_code_1"/>

10 <constructor-arg index="1" value="test_goods_code_1"/>

11 </bean>

12 <bean id="goods" class="com.lucky.test.spring.demo.GoodsService" init-method="init">

13 <constructor-arg index="0" value="test_order_code_2"/>

14 <constructor-arg index="1" value="test_goods_code_2"/>

15 </bean>

16

17 <bean id="myBeanPostProcessor" class="com.lucky.test.spring.demo.MyBeanPostProcessor"/>

18

19 </beans>

本案例中,分别声明两个GoodsService类的bean,一个beanName为goodsService,一个beanName为goods,而自定义的后置处理器只处理beanName的后缀为Service的bean,所以这里会处理goodsService这个bean,测试代码如下:

1 public static void main(String[] args) throws Exception {

2 ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("application.xml");

3 GoodsService goodsService = context.getBean("goodsService", GoodsService.class);

4 GoodsService goods = context.getBean("goods", GoodsService.class);

5 System.out.println(goodsService.getGoodsCode());

6 System.out.println(goods.getGoodsCode());

7 }

从容器中获取这两个bean,分别调用getGoodsCode()方法,由于在配置bean的时候才有的构造器方式注入属性,所以该bean的goodsCode属性应该是有值的,测试结果如下:

1 后置处理器 初始化方法之前执行

2 执行init方法

3 后置处理器 初始化方法之后执行

4 通过类的newInstance方法创造对象

5 后置处理器 初始化方法之前执行

6 执行init方法

7 后置处理器 初始化方法之后执行

8 null

9 test_order_code_2

可以看出goodsService这个bean被后置处理器重新处理了,才有newInstance方法重新创建了一个对象,替换了通过构造器创建的bean,所以原先通过构造器方法注入的属性值为null,而goods这个bean没有被后置处理器处理,还是构造器创建的bean对象。

从案例可以看出,后置处理器可以对Spring容器中的bean做很多的后置处理,比如强制执行bean的某些方法,给bean注入属性,甚至是直接将初始化的bean直接替换掉也可以。

3、后置处理器的实现原理

在Spring容器初始化的时候,会初始化所有的后置处理器,而后置处理器本身也是一个bean,所以也是归Spring容器所管理的,当bean初始化的过程中,会从Spring容器中获取所有的后置处理器,分别遍历执行后置处理器的方法,从而来对bean进行处理。

3.1、初始化后置处理器

Spring容器BeanFactory的子接口ConfigurableBeanFactory接口中定义了方法addPostProcessor,用于容器动态添加后置处理器

1 void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);

该接口的默认实现类是AbstractBeanFactory,实现代码如下:

1 /** Spring容器的后置处理器集合 */

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

3

4 /** Indicates whether any InstantiationAwareBeanPostProcessors have been registered. */

5 private volatile boolean hasInstantiationAwareBeanPostProcessors;

6

7 /** Indicates whether any DestructionAwareBeanPostProcessors have been registered. */

8 private volatile boolean hasDestructionAwareBeanPostProcessors;

9

10 @Override

11 public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {

12 // 从List中先删除该处理器

13 this.beanPostProcessors.remove(beanPostProcessor);

14 // Track whether it is instantiation/destruction aware

15 if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {

16 this.hasInstantiationAwareBeanPostProcessors = true;

17 }

18 if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {

19 this.hasDestructionAwareBeanPostProcessors = true;

20 }

21 //将后置处理器加入List中

22 this.beanPostProcessors.add(beanPostProcessor);

23 }

addBeanPostProcessor方法的逻辑比较简单,Spring容器内部有一个所有后置处理器的列表,每次加入新的后置处理器,就会加入到列表中即可,另外还有两个boolean类型的属性,分别表示如果当前加入的后置处理器如果是指定的类型,就将指定的属性值置为true

3.2、 添加后置处理器

从3.1可知Spring容器会保存所有后置处理器,所以就需要向Spring容器去添加,添加的逻辑是在Spring容器初始化的时候。Spring容器初始化的时候执行refresh()方法时,该方法内会注册所有后置和处理器,方法如下:

1 /** 注册所有后置处理器*/

2 registerBeanPostProcessors(beanFactory);

该方法会注册所有后置处理器到Spring容器中,实际也就是调用3.1中的addBeanPostProcesser方法,后置处理器实际的执行是给getBean的过程中,准确点将是在bean初始化的过程中。

接下来就看下是如何注册所有后置处理器的,registerBeanPostProcessors方法源码如下:

1 /** 委托PostProcessorRegistrationDelegate来给当前容器注册后置处理器*/

2 protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {

3 PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);

4 }

5

6 /**

7 * Spring容器注册后置处理器

8 * @param beanFactory:加载了所有bean的容器

9 * @param applicationContext:当前Spring上下文

10 * @deprecated 从beanFactory中找到所有BeanPostProcessor接口的bean加入到applicationContext中

11 * */

12 public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

13

14 /**

15 * 1. 从BeanFactory中找到所有BeanPostProcessor的bean

16 * */

17 String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

18

19 int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;

20 //注册BeanPostProcessorChecker后置处理器,该处理器用于校验后置处理器的注册

21 beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

22

23 /**

24 * 2.定义了多个后置处理器列表

25 * priorityOrderedPostProcessors用于存储实现了PriorityOrdered接口的后置处理器(用于排序)

26 * orderedPostProcessorNames用于存储实现了Ordered接口的后置处理器(用于排序)

27 * nonOrderedPostProcessorNames用于存储没有实现排序接口的后置处理器

28 * */

29 List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();

30 List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();

31 List<String> orderedPostProcessorNames = new ArrayList<>();

32 List<String> nonOrderedPostProcessorNames = new ArrayList<>();

33 /**

34 * 3.遍历所有后置处理器

35 * */

36 for (String ppName : postProcessorNames) {

37 if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {

38 BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);

39 //3.1.将实现了PriorityOrdered接口的后置处理器加入到对应列表中

40 priorityOrderedPostProcessors.add(pp);

41 if (pp instanceof MergedBeanDefinitionPostProcessor) {

42 internalPostProcessors.add(pp);

43 }

44 }

45 else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {

46 //3.2.将实现了Ordered接口的后置处理器加入到对应列表中

47 orderedPostProcessorNames.add(ppName);

48 }

49 else {

50 //3.3.没有实现排序接口的后置处理器加入到对应列表中

51 nonOrderedPostProcessorNames.add(ppName);

52 }

53 }

54

55 /**

56 * 4.分别将三个列表中的后置处理器进行排序,注册到Spring容器中

57 * */

58 //4.1.将实现了PriorityOrdered接口的后置处理器进行排序

59 sortPostProcessors(priorityOrderedPostProcessors, beanFactory);

60 //4.2.将排序后的列表注册到容器中

61 registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

62

63

64 List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());

65 for (String ppName : orderedPostProcessorNames) {

66 BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);

67 orderedPostProcessors.add(pp);

68 if (pp instanceof MergedBeanDefinitionPostProcessor) {

69 internalPostProcessors.add(pp);

70 }

71 }

72 //4.3.将实现了Ordered接口的后置处理器进行排序

73 sortPostProcessors(orderedPostProcessors, beanFactory);

74 //4.4.将排序后的列表注册到容器中

75 registerBeanPostProcessors(beanFactory, orderedPostProcessors);

76

77 List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());

78 for (String ppName : nonOrderedPostProcessorNames) {

79 BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);

80 nonOrderedPostProcessors.add(pp);

81 if (pp instanceof MergedBeanDefinitionPostProcessor) {

82 internalPostProcessors.add(pp);

83 }

84 }

85 //4.5将所有无序的列表注册到Spring容器中

86 registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

87

88 //4.6将所有实现了MergedBeanDefinitionPostProcessor接口的后置处理器进行排序

89 sortPostProcessors(internalPostProcessors, beanFactory);

90 //4.6.将排序后的列表注册到Spring容器中

91 registerBeanPostProcessors(beanFactory, internalPostProcessors);

92

93 //5.添加ApplicationListenerDetector类型的后置处理器

94 beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));

95 }

96

97 private static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {

98

99 /** 遍历执行Spring容器的addBeanPostProcessor方法 */

100 for (BeanPostProcessor postProcessor : postProcessors) {

101 beanFactory.addBeanPostProcessor(postProcessor);

102 }

103 }

从源码上逻辑也比较清晰,总结步骤如下:

1、从BeanFactory中根据BeanPostProcessor类型找到所有注册的后置处理器的bean

2、判断后置处理器是否实现了PriorityOrdered接口、Ordered接口和没有实现任何排序接口,分别加入到对应的列表中

3、分别对各个列表中的后置处理器进行排序,然后遍历加入到Spring容器中

Tip:

1、PriorityOrdered接口是继承之Ordered接口,该接口没有额外定义方法,所以仅仅是起到了一个标志的作用,而Ordered接口是用于排序

2、后置处理器的注册顺序为,优先所有PriorityOrdered实现类进行排序;再按Ordered实现类进行排序,最后才注册所有无序的后置处理器

4、BeanPostProcessor的子接口

BeanPostProcessor只有两个方法,一个是在bean初始化之前执行,一个是在bean初始化之后执行,而除了这两个方法,Spring还提供了在其他情况下执行的后置处理逻辑,这就需要使用BeanPostProcessor的子接口来实现。

4.1、InstantiationAwareBeanPostProcessor

用于处理bean实例化前后的处理操作,Spring容器获取bean时需要先创建bean(实例化),然后在对bean的属性进行赋值(初始化),BeanPostProcessor接口的两个方法分别是在bean初始化前后来执行的,而InstanitationAwareBeanPostProcessor提供的方法则是分别在Bean实例化前后来处理的方法,提供的方法如下:

1 public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {

2

3 /**

4 * bean实例化之前直接返回一个对象(如代理对象)来代替通过构造器创建的对象

5 */

6 @Nullable

7 default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {

8 return null;

9 }

10

11 /**

12 * bean实例化之后,在populateBean方法中执行,在setter属性注入之前执行

13 * 如果返回true表示需要属性依赖注入

14 * 如果返回false表示不需要属性依赖注入

15 */

16 default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {

17 return true;

18 }

19

20 /**

21 * 对于bean的属性值进行设置操作,在populateBean方法中执行,在setter属性注入之前执行

22 */

23 @Nullable 24 default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)

25 throws BeansException {

27 return null;

28 }

29 }

InstantiationAwareBeanPostProcessor接口在父接口BeanPostProcessor的基础之上添加了三个方法,分别是在bean实例化前后以及属性注入之前设置属性三个方法。执行的源码如下:

4.1.1、postProcessBeforeInstantiation方法执行

bean的实例是调用容器的createBean方法来进行创建,createBean方法逻辑代码如下:

1 @Override

2 protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)

3 throws BeanCreationException {

4 RootBeanDefinition mbdToUse = mbd;

5 mbdToUse.prepareMethodOverrides();

6

7 /***

8 * 1.通过InstantiationAwareBeanPostProcessor 实例化bean

9 * * */

10 Object bean = resolveBeforeInstantiation(beanName, mbdToUse);

11 if (bean != null) {

12 return bean;

13 }

14

15 /**

16 * 2.通过构造函数实例bean

17 * */

18 Object beanInstance = doCreateBean(beanName, mbdToUse, args);

19 return beanInstance;

20 }

1 @Nullable

2 protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {

3 Object bean = null;

4 if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {

5 /** 判断容器中是否有 InstantiationAwareBeanPostProcessor 后置处理器*/

6 if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {

7 Class<?> targetType = determineTargetType(beanName, mbd);

8 if (targetType != null) {

9 /** 执行applyBeanPostProcessorBeforeInstantiation方法*/

10 bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);

11 if (bean != null) {

12 bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);

13 }

14 }

15 }

16 mbd.beforeInstantiationResolved = (bean != null);

17 }

18 return bean;

19 }

20

21 @Nullable

22 protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {

23 /**

24 * 遍历所有的InstantiationAwareBeanPostProcessor,依次执行postProcessBeforeInstantiation方法

25 * */

26 for (BeanPostProcessor bp : getBeanPostProcessors()) {

27 if (bp instanceof InstantiationAwareBeanPostProcessor) {

28 InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;

29 Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);

30 if (result != null) {

31 return result;

32 }

33 }

34 }

35 return null;

36 }

整体逻辑比较清晰,createBean时先通过InstantationAwareBeanPostProcessor后置处理器处理,从容器中找到所有InstantationAwareBeanPostProcessor,然后遍历一次执行postProcessorBeforeInstantiation方法,执行完之后如果bean不为空,表示当前的bean不需要通过构造器来创建,而是直接通过后置处理器来创建的,此时就不会在执行doCreateBean方法来。如果没有后置处理器,才会执行doCreateBean方法通过构造器的方式来创建bean

4.1.2、postProcessAfterInstantiation方法和postProcessProperties方法执行

postProcessAfterInstantiation方法是在方法实例化之后执行,在属性填充之前执行,在doCreateBean方法之中,会先通过构造器方法创建bean,然后调用populateBean方法对bean进行填充,方法如下:

1 protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {

2

3 /**

4 * 1、遍历所有的InstantiationAwareBeanPostProcessor后置处理器

5 * 依次执行postProcessAfterInstantiation方法

6 * */

7 if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {

8 for (BeanPostProcessor bp : getBeanPostProcessors()) {

9 if (bp instanceof InstantiationAwareBeanPostProcessor) {

10 InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;

11 if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {

12 return;

13 }

14 }

15 }

16 }

17

18 PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

19

20 /**

21 * 2.属性注入

22 * */

23 int resolvedAutowireMode = mbd.getResolvedAutowireMode();

24 if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {

25 MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

26 // Add property values based on autowire by name if applicable.

27 if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {

28 autowireByName(beanName, mbd, bw, newPvs);

29 }

30 // Add property values based on autowire by type if applicable.

31 if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {

32 autowireByType(beanName, mbd, bw, newPvs);

33 }

34 pvs = newPvs;

35 }

36

37 boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();

38 boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

39

40 PropertyDescriptor[] filteredPds = null;

41 if (hasInstAwareBpps) {

42 if (pvs == null) {

43 pvs = mbd.getPropertyValues();

44 }

45 /**

46 * 3.遍历所有的InstantiationAwareBeanPostProcessor后置处理器

47 * 依次执行postProcessProperties方法

48 * */

49 for (BeanPostProcessor bp : getBeanPostProcessors()) {

50 if (bp instanceof InstantiationAwareBeanPostProcessor) {

51 InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;

52 PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);

53 if (pvsToUse == null) {

54 if (filteredPds == null) {

55 filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);

56 }

57 pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);

58 if (pvsToUse == null) {

59 return;

60 }

61 }

62 pvs = pvsToUse;

63 }

64 }

65 }

66 if (needsDepCheck) {

67 if (filteredPds == null) {

68 filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);

69 }

70 checkDependencies(beanName, mbd, filteredPds, pvs);

71 }

72

73 if (pvs != null) {

74 applyPropertyValues(beanName, mbd, bw, pvs);

75 }

76 }

可以看出逻辑比较清晰,先是遍历所有的后置处理器,依次执行postProcessAfterInstantiation方法,然后是对bean进行依赖注入,然后在遍历所有的后置处理器,依次执行postProcessProperties方法进行属性设置

4.2、MergedBeanDefinitionPostProcessor

MergedBeanDefiniationPostProcessor是用于合并bean定义时用到的处理器,当一个bean存在有父bean时,在初始化bean之后,需要将父bean的属性合并到该bean的实例中。另外对于bean需要注入的元数据,也可以通过该处理器来对bean进行属性注入,

比如Spring框架中常用到的@Autowired注解就是通过MergedBeanDefinitionPostProcessor来实现的,因为通过@Autowired注解注入的属性是没有setter方法的,也不是通过构造器注入的,所以需要额外的处理器来对bean的属性进行注入。

MergedBeanDefiniationPostProcessor接口方法定义如下:

1 public interface MergedBeanDefinitionPostProcessor extends BeanPostProcessor {

2

3 /**

4 * bean实例化执行,用于处理合并beanDefinition的属性,比如非构造器和setter注入的属性

5 * 在bean实例化执行;属性填充之前执行

6 */

7 void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);

8

9 /**

10 * 重置bean的定义BeanDefinition

11 */

12 default void resetBeanDefinition(String beanName) {

13 }

14

15 }

MergedBeanDefiniationPostProcessor的执行时间是在bean实例化之后,属性填充方法popluate方法执行之前执行。同样也是在doCreateBean方法中执行的,逻辑如下:

1 protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)

2 throws BeanCreationException {

3

4 /**

5 * 1、通过构造器创建bean

6 * */

7 BeanWrapper instanceWrapper = null;

8 if (instanceWrapper == null) {

9 instanceWrapper = createBeanInstance(beanName, mbd, args);

10 }

11

12 /**

13 * 2、遍历执行MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition方法

14 * */

15 synchronized (mbd.postProcessingLock) {

16 if (!mbd.postProcessed) {

17 try {

18 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);

19 }

20 catch (Throwable ex) {

21 throw new BeanCreationException(mbd.getResourceDescription(), beanName,

22 "Post-processing of merged bean definition failed", ex);

23 }

24 mbd.postProcessed = true;

25 }

26 }

27

28 Object exposedObject = bean;

29 try {

30 /**

31 * 3.属性填充

32 * */

33 populateBean(beanName, mbd, instanceWrapper);

34 /**

35 * 4.执行初始化方法

36 * */

37 exposedObject = initializeBean(beanName, exposedObject, mbd);

38 }

39 return exposedObject;

40 }

1 /**

2 * 遍历执行后置处理器的 postProcessMergedBeanDefinition 方法

3 * */

4 protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {

5 for (BeanPostProcessor bp : getBeanPostProcessors()) {

6 if (bp instanceof MergedBeanDefinitionPostProcessor) {

7 MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;

8 bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);

9 }

10 }

11 }

4.3、SmartInstantiationAwareBeanPostProcessor

SmartInstantiationAwareBeanPostProcessor继承之InstantiationAwareBeanPostProcessor,在InstantiationAwareBeanPostProcessor接口的基础之上又额外定义了几个方法,源码如下:

1 public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {

2

3 /**

4 * 获取目标对象bean的类型

5 */

6 @Nullable

7 default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {

8 return null;

9 }

10

11 /**

12 * 获取用于对象实例化的构造器对象(在创建bean的时候调用)

13 */

14 @Nullable

15 default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)

16 throws BeansException {

17

18 return null;

19 }

20

21 /**

22 * 获取提前曝光的单例bean对象

23 */

24 default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {

25 return bean;

26 }

27 }

4.4、DestructionAwareBeanPostProcessor

DestructionAwareBeanPostProcessor是用于处理bean销毁的时候进行后置处理,方法定义如下:

1 public interface DestructionAwareBeanPostProcessor extends BeanPostProcessor {

2

3 /**

4 * 当bean销毁的时候后置处理

5 */

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

7

8 /**

9 * 判断bean销毁的时候实现需要处理

10 */

11 default boolean requiresDestruction(Object bean) {

12 return true;

13 }

14 }

5、Spring的核心后置处理器**(*)**

5.1、AutowiredAnnotationBeanPostProcessor(@Autowired注解处理器)

AutowiredAnnotationBeanPostProcessor既实现了SmartInstantiationAwareBeanPostProcessor接口又实现了MergedBeanDefinitionPostProcessor接口,按执行顺序来看,bean加载的过程中方法的执行顺序如下:

1、执行SmartInstantiationAwareBeanPostProcessor接口的determineCandidateConstructors方法(找到bean的构造器方法)

2、执行MergedBeanDefinitionPostProcessor接口的postProcessMergedBeanDefinition方法(注入元属性)

3、执行InstantiationAwareBeanPostProcessor接口的postProcessProperties方法(属性设置)

5.1.1、determineCandidateConstructors方法的作用了找到该bean所有的构造器对象

5.1.2、postProcessMergedBeanDefinition方法实现逻辑如下:

1、遍历该bean所有的属性,找到被@Autowired、@Value、@Inject等注解修饰的属性,封装成AutowiredFieldElement对象,加入到列表中

2、遍历该bean所有的方法,找到被@Autowired、@Value、@Inject等注解修饰的方法,封装成AutowiredMethodElement对象,加入到列表中

3、将1、2步找到的两个列表,加入到一个InjectedElement列表中

4、根据InjectedElement列表和Class对象,封装成InjectedMetadata对象

5.1.3、postProcessProperties方法实现逻辑如下:

1、获取或构造5.1.2中的InjectedMetadata对象

2、执行InjectedMetadata对象的inject方法注入元属性

3、遍历InjectedMetadata对象的InjectedElement列表,依次执行InjectedElement对象的inject方法

4、InjectedElement的inject的逻辑如下,从容器中找到需要注入的bean,然后通过反射来进行注入:

4.1、如果当前Element是属性,那么就通过反射先调用Field的setAccessible(true)设置Field可以操作,然后通过反射调用Field的set(Obejct target, Object value)方法设置属性的值

4.2、如果当前Element是方法,那么就通过反射调用Method的setAccessible(true)设置Method可以操作,然后通过反射调用Method的invoke(Obejct obj, Object...args)方法执行方法

5.2、CommonAnnotationBeanPostProcessor(@Resource注解处理器)

CommonAnnotationBeanPostProcessor的作用是处理@Resource用的,当某个bean中定义了@Resource来修饰属性或者方法,那么该后置处理器就会将该bean依赖的bean注入进去,具体的实现逻辑和5.1的处理@Autowired注解的逻辑基本上一致。

只不过5.1是遍历bean的属性或方法中的@Autowired注解,而CommonAnnotationBeanPostProcessor是遍历属性或方法修饰的@Resource注解,注入的逻辑是一样的,都是通过InjectedMetadata类来实现的。

5.3、ApplicationContextAwareProcessor(Aware子接口方法执行)

Spring框架提供了众多的Aware接口,如ApplicationContextAware、MessageSoureceAware接口等,bean如果实现了对应的接口,就需要实现对应的set方法,而这些set方法的执行就是通过ApplicationContextAwareProcessor来执行的,

ApplicationContextAwareProcessor实现了BeanPostProcessor的postProcessBeforeInitialization方法,所以会在bean初始化之前执行,会依次执行Context包中提供的Aware子接口对应的set方法

6、Extra(*)

加载bean时各种BeanPostProcessor执行的时序图如下图示

本文内容总结:前言,1、BeanPostProcessor接口,2、后置处理器的使用,3、后置处理器的实现原理,3.1、初始化后置处理器,3.2、 添加后置处理器,4、BeanPostProcessor的子接口,4.1、InstantiationAwareBeanPostProcessor,4.2、MergedBeanDefinitionPostProcessor,4.3、SmartInstantiationAwareBeanPostProcessor,4.4、DestructionAwareBeanPostProcessor,5、Spring的核心后置处理器(),5.1、AutowiredAnnotationBeanPostProcessor(@Autowired注解处理器),5.2、CommonAnnotationBeanPostProcessor(@Resource注解处理器),5.3、ApplicationContextAwareProcessor(Aware子接口方法执行),6、Extra(),

原文链接:https://www.cnblogs.com/jackion5/p/13325136.html

以上是 Spring扩展接口解析4--bean后置处理器BeanPostProcessor接口 的全部内容, 来源链接: utcz.com/z/362514.html

回到顶部