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

前言

众所周知,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执行的时序图如下图示

原文地址:https://www.cnblogs.com/jackion5/p/13325136.html