Spring源码学习笔记(七、Spring启动流程解析:调用后处理器)
目录:
- 准备工作
- BeanFactory后处理源码解析:invokeBeanFactoryPostProcessors
准备工作
在了解BeanFactory后处理源码前首先我们需要先了解几个东西:
1、BeanPostProcessor、BeanFactoryPostProcessor区别:
这两个从名字来看可能很相似,但处理的事是完全不一样的
- BeanPostProcessor是针对bean实例化后做的定制处理,会在bean初始化前后做处理。
- BeanFactoryPostProcessor是用来操作bean元数据的,也可以说是操作配置文件的,是在定义bean阶段的后置处理。
你可以这样理解,bean就是你的孩子,BeanPostProcessor就是你在你孩子出生后给他的一些规划,怎么培养他等等;而BeanFactoryPostProcessor就是你在你孩子出生前给他的一些定制操作,比如网上说的多吃葡萄生出的孩子眼睛大,哈哈哈哈。
———————————————————————————————————————————————————————
2、BeanDefinitionRegistryPostProcessor:
BeanDefinitionRegistryPostProcessor是对标准BeanFactoryPostProcessor的扩展,允许在进行常规BeanFactoryPostProcessor检测之前注册其他Bean定义。
特别是,BeanDefinitionRegistryPostProcessor注册的Bean定义,又定义了BeanFactoryPostProcessor实例。
———————————————————————————————————————————————————————
3、自定义BeanFactoryPostProcessor:
了解了第1、2两个点之后,我们就看看如何自定义BeanFactoryPostProcessor。
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" 4 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> 5 6 <bean class="com.jdr.spring.postprocessor.bean.Car" name="car"> 7 <property name="name" value="benz"/> 8 </bean> 9 10 <bean class="com.jdr.spring.postprocessor.CarBeanFactoryPostProcess1" name="carBeanFactoryPostProcess1"> 11 <property name="order" value="0"/> 12 </bean> 13 14 <bean class="com.jdr.spring.postprocessor.CarBeanFactoryPostProcess2" name="beanFactoryPostProcess2"> 15 <property name="order" value="1"/> 16 </bean> 17 18 <bean class="com.jdr.spring.postprocessor.MobileBeanFactoryPostProcessor" name="mobileBeanFactoryPostProcessor"/> 19 20 </beans>
1 public class Car { 2 3 private String name; 4 private String color; 5 6 // getter and setter 7 8 public String getName() { 9 return name; 10 } 11 12 public void setName(String name) { 13 this.name = name; 14 } 15 16 public String getColor() { 17 return color; 18 } 19 20 public void setColor(String color) { 21 this.color = color; 22 } 23 }
配置文件很简单,就是定义了一些bean,以及设置了他们的属性。
如果我现在就执行的话,肯定能的到Car的name=benz,color=null,如果我们想改变其属性的话就可以通过BeanFactoryPostProcessor来实现,也就是通过BeanFactoryPostProcessor操作元数据。
1 public class CarBeanFactoryPostProcess1 implements BeanFactoryPostProcessor, Ordered { 2 3 private int order; 4 5 @Override 6 public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { 7 System.out.println("invoke CarBeanFactoryPostProcess1..."); 8 BeanDefinition car = beanFactory.getBeanDefinition("car"); 9 // 重置name属性 10 car.getPropertyValues().addPropertyValue("name", "BMW"); 11 } 12 13 @Override 14 public int getOrder() { 15 return this.order; 16 } 17 18 // getter and setter 19 20 public void setOrder(int order) { 21 this.order = order; 22 } 23 } 24 25 public class CarBeanFactoryPostProcess2 implements BeanFactoryPostProcessor, Ordered { 26 27 private int order; 28 29 @Override 30 public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { 31 System.out.println("invoke CarBeanFactoryPostProcess2..."); 32 BeanDefinition car = beanFactory.getBeanDefinition("car"); 33 // 添加color属性 34 car.getPropertyValues().addPropertyValue("color", "red"); 35 } 36 37 @Override 38 public int getOrder() { 39 return this.order; 40 } 41 42 // getter and setter 43 44 public void setOrder(int order) { 45 this.order = order; 46 } 47 }
经过这一番操作,就将元数据修改了,name=BMW,color=red。
同样的,我们可以通过实现BeanDefinitionRegistryPostProcessor来定义bean,而不是通过xml来配置,如下:
1 public class MobileBeanFactoryPostProcessor implements BeanDefinitionRegistryPostProcessor { 2 3 @Override 4 public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { 5 // 定义bean 6 System.out.println("invoke MobileBeanFactoryPostProcessor postProcessBeanDefinitionRegistry..."); 7 BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(Mobile.class); 8 registry.registerBeanDefinition("mobile", builder.getBeanDefinition()); 9 } 10 11 @Override 12 public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { 13 // 定义bean后的处理 14 System.out.println("invoke MobileBeanFactoryPostProcessor postProcessBeanFactory..."); 15 BeanDefinition mobile = beanFactory.getBeanDefinition("mobile"); 16 mobile.getPropertyValues().addPropertyValue("number", "123456"); 17 } 18 }
4、先有bean的定义,还是bean的实例化:
毋庸置疑,肯定只有bean被定义好了后才能正常实例化bean;也就是说BeanDefinitionRegistryPostProcessor肯定优先于BeanFactoryPostProcessor执行(这个等会会在源码里看到)。
5、PriorityOrdered和Ordered:
Priority定义如下,仅仅是继承Ordered,但含义却不一样,是优先于Ordered的排序。
1 public interface PriorityOrdered extends Ordered { 2 }
BeanFactory后处理源码解析:invokeBeanFactoryPostProcessors
这部分的源码非常简单,很容易理解。
1 public static void invokeBeanFactoryPostProcessors( 2 ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { 3 4 // 记录以及执行过的BeanDefinitionRegistryPostProcessors,以免重复执行 5 Set<String> processedBeans = new HashSet<String>(); 6 7 // 若beanFactory是实现了BeanDefinitionRegistry 8 // 其实也就是指DefaultListableBeanFactory或者GenericApplicationContext 9 if (beanFactory instanceof BeanDefinitionRegistry) { 10 BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; 11 // 存放普通的BeanFactoryPostProcessor 12 List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>(); 13 // 存放已经执行注册函数的BeanDefinitionRegistryPostProcessor 14 List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList<BeanDefinitionRegistryPostProcessor>(); 15 16 // 上面的准备工作中已经提到BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的扩展,提供了注册bean的功能 17 // 所以说这段代码的含义就是,若postProcessor是BeanDefinitionRegistryPostProcessor的话先执行注册的函数,再将其放到registryProcessors中 18 // 否则将其放到常规的,仅提供了后置处理操作的regularPostProcessors中 19 for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { 20 if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { 21 BeanDefinitionRegistryPostProcessor registryProcessor = 22 (BeanDefinitionRegistryPostProcessor) postProcessor; 23 registryProcessor.postProcessBeanDefinitionRegistry(registry); 24 registryProcessors.add(registryProcessor); 25 } 26 else { 27 regularPostProcessors.add(postProcessor); 28 } 29 } 30 31 // 当前要注册的BeanDefinitionRegistryPostProcessor集合 32 List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>(); 33 34 // 拿出beanFactory中所有类型为BeanDefinitionRegistryPostProcessor的beanName 35 // 如果其实现了PriorityOrdered接口,就先将其放入到currentRegistryProcessors中 36 String[] postProcessorNames = 37 beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); 38 for (String ppName : postProcessorNames) { 39 if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { 40 currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); 41 processedBeans.add(ppName); 42 } 43 } 44 // 执行了currentRegistryProcessors的排序、添加到已注册集合中、执行注册函数、清空集合操作 45 sortPostProcessors(currentRegistryProcessors, beanFactory); 46 registryProcessors.addAll(currentRegistryProcessors); 47 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); 48 currentRegistryProcessors.clear(); 49 50 // 步骤同上,只是这里只会执行实现了Ordered接口的postProcessorNames 51 // 这里也可以证实了我“准备工作”中所提到了:PriorityOrdered优先于Ordered的执行 52 postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); 53 for (String ppName : postProcessorNames) { 54 if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) { 55 currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); 56 processedBeans.add(ppName); 57 } 58 } 59 sortPostProcessors(currentRegistryProcessors, beanFactory); 60 registryProcessors.addAll(currentRegistryProcessors); 61 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); 62 currentRegistryProcessors.clear(); 63 64 // 最后一步,调用其它的BeanDefinitionRegistryPostProcessor,也就是未实现排序接口的 65 boolean reiterate = true; 66 while (reiterate) { 67 reiterate = false; 68 postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); 69 for (String ppName : postProcessorNames) { 70 if (!processedBeans.contains(ppName)) { 71 currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); 72 processedBeans.add(ppName); 73 reiterate = true; 74 } 75 } 76 sortPostProcessors(currentRegistryProcessors, beanFactory); 77 registryProcessors.addAll(currentRegistryProcessors); 78 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); 79 currentRegistryProcessors.clear(); 80 } 81 82 // 当所有的已注册完毕,就先调用registryProcessors的bean后置处理回调,再调regularPostProcessors的后置回调 83 invokeBeanFactoryPostProcessors(registryProcessors, beanFactory); 84 invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory); 85 } 86 87 else { 88 // 如果不是BeanDefinitionRegistry,说明不会注册bean,直接调用bean的后置处理即可 89 invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory); 90 } 91 92 // 这里之后的代码和上面类似,只不过此处只处理BeanFactoryPostProcessor 93 // 也是根据优先级来,PriorityOrdered > Ordered > Normal 94 // 并执行他们的bean后置处理函数 95 // 我相信只要你把前面的代码读懂了,这部分是非常容易理解的,哈哈哈哈哈哈 96 String[] postProcessorNames = 97 beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false); 98 99 // Separate between BeanFactoryPostProcessors that implement PriorityOrdered, 100 // Ordered, and the rest. 101 List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>(); 102 List<String> orderedPostProcessorNames = new ArrayList<String>(); 103 List<String> nonOrderedPostProcessorNames = new ArrayList<String>(); 104 for (String ppName : postProcessorNames) { 105 if (processedBeans.contains(ppName)) { 106 // skip - already processed in first phase above 107 } 108 else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { 109 priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class)); 110 } 111 else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { 112 orderedPostProcessorNames.add(ppName); 113 } 114 else { 115 nonOrderedPostProcessorNames.add(ppName); 116 } 117 } 118 119 // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered. 120 sortPostProcessors(priorityOrderedPostProcessors, beanFactory); 121 invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); 122 123 // Next, invoke the BeanFactoryPostProcessors that implement Ordered. 124 List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>(); 125 for (String postProcessorName : orderedPostProcessorNames) { 126 orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); 127 } 128 sortPostProcessors(orderedPostProcessors, beanFactory); 129 invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory); 130 131 // Finally, invoke all other BeanFactoryPostProcessors. 132 List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>(); 133 for (String postProcessorName : nonOrderedPostProcessorNames) { 134 nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); 135 } 136 invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory); 137 138 // Clear cached merged bean definitions since the post-processors might have 139 // modified the original metadata, e.g. replacing placeholders in values... 140 beanFactory.clearMetadataCache(); 141 }