zoukankan      html  css  js  c++  java
  • 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执行的时序图如下图示

  • 相关阅读:
    宜未雨而绸缪,毋临渴而掘井。
    JDBC fetch size
    社会主义核心价值观
    JavaEE
    《夜泊牛渚怀古》
    JAVA "GMT+10" 和 "GMT+0010"
    乡村振兴1
    申论 题好文一半
    UCOS时钟与中断:
    任务的状态-挂起和恢复
  • 原文地址:https://www.cnblogs.com/jackion5/p/13325136.html
Copyright © 2011-2022 走看看