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