更多文章点击--spring源码分析系列
主要分析内容:
一、BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor简述与demo示例
二、BeanFactoryPostProcessor源码分析:注册时机和触发点
(源码基于spring 5.1.3.RELEASE分析)
一、BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor简述与demo示例
1、BeanFactoryPostProcessor是spring容器级别的拓展接口,是在BeanDefinition加载完成之后,未实例化之前.可以拓展接口,对定制化修改BeanDefinition.
1 public interface BeanFactoryPostProcessor { 2 3 void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException; 4 }
2、BeanDefinitionRegistryPostProcessor继承自BeanFactoryPostProcessor,是一种比较特殊的BeanFactoryPostProcessor。
BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry方法可实现自定义的bean注册定义。
通常spring注册bean使用静态方式, 如:xml、@Bean注解或@Component方式实现注册.不能通过程序来选择是否注册。
而实现BeanDefinitionRegistryPostProcessor的类可以获得BeanDefinitionRegistry 对象,通过它可以动态的注册组件,是实现动态注册的钩子函数。spring典型的ConfigurationClassPostProcessor拓展BeanDefinitionRegistryPostProcessor 解析@Configuration配置类 .
1 public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor { 2 3 void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException; 4 }
demo示例:
![](http://img.e-com-net.com/image/info8/b8d97b5613f94ed2ba791cad57d0b2ed.gif)
![](http://img.e-com-net.com/image/info8/2f88dd3f1cd145f59c0e47b51acdbd4b.gif)
1 public class CustomBeanDefinitionRegistry implements BeanDefinitionRegistryPostProcessor { 2 3 @Override 4 public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { 5 GenericBeanDefinition definition = new GenericBeanDefinition(); 6 //设置类 7 definition.setBeanClass(RegistryBean.class); 8 //设置scope 9 definition.setScope("singleton"); 10 //设置是否懒加载 11 definition.setLazyInit(false); 12 //设置是否可以被其他对象自动注入 13 definition.setAutowireCandidate(true); 14 15 // 给属性赋值 16 MutablePropertyValues mpv = new MutablePropertyValues() ; 17 mpv.add("name", "CustomBeanDefinitionRegistry settings") ; 18 definition.setPropertyValues(mpv); 19 20 registry.registerBeanDefinition("registryBean", definition); 21 } 22 23 24 @Override 25 public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { 26 // do noting 27 28 } 29 }
![](http://img.e-com-net.com/image/info8/b8d97b5613f94ed2ba791cad57d0b2ed.gif)
![](http://img.e-com-net.com/image/info8/2f88dd3f1cd145f59c0e47b51acdbd4b.gif)
1 public class LogicBeanFactoryPostProcessor implements BeanFactoryPostProcessor { 2 3 @Override 4 public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { 5 BeanDefinition bd = beanFactory.getBeanDefinition("bean") ; 6 MutablePropertyValues mpv = null ; 7 if(bd != null && (mpv = bd.getPropertyValues())!=null){ 8 PropertyValue value = mpv.getPropertyValue("name"); 9 System.out.print("修改之前 a 的value是:"+value.getValue()+"\n"); 10 value.setConvertedValue("postProcessBeanFactory修改属性"); 11 } 12 } 13 }
![](http://img.e-com-net.com/image/info8/b8d97b5613f94ed2ba791cad57d0b2ed.gif)
![](http://img.e-com-net.com/image/info8/2f88dd3f1cd145f59c0e47b51acdbd4b.gif)
1 public class RegistryBean { 2 3 public RegistryBean(){ 4 5 } 6 7 public RegistryBean(String name){ 8 this.name = name ; 9 } 10 11 private String name ; 12 13 14 public String getName() { 15 return name; 16 } 17 18 public void setName(String name) { 19 this.name = name; 20 } 21 22 @Override 23 public String toString() { 24 return "RegistryBean{" + 25 "name='" + name + '\'' + 26 '}'; 27 } 28 }
![](http://img.e-com-net.com/image/info8/b8d97b5613f94ed2ba791cad57d0b2ed.gif)
![](http://img.e-com-net.com/image/info8/2f88dd3f1cd145f59c0e47b51acdbd4b.gif)
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:p="http://www.springframework.org/schema/p" 4 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> 5 6 <bean id="bean" class="com.nancy.ioc.Bean"> 7 <property name="name" value="zhouxiaoxing"/> 8 bean> 9 10 <bean id="logicBeanFactoryPostProcessor" class="com.nancy.ioc.BeanFactoryPostProcessor.LogicBeanFactoryPostProcessor"/> 11 <bean id="customBeanDefinitionRegistry" class="com.nancy.ioc.BeanFactoryPostProcessor.CustomBeanDefinitionRegistry"/> 12 13 beans>
![](http://img.e-com-net.com/image/info8/b8d97b5613f94ed2ba791cad57d0b2ed.gif)
![](http://img.e-com-net.com/image/info8/2f88dd3f1cd145f59c0e47b51acdbd4b.gif)
1 public class BeanFactoryPostProcessorTest { 2 private ApplicationContext applicationContext ; 3 4 @Before 5 public void beforeApplicationContext(){ 6 /** 7 * ApplicationContext 自动注册 BeanPostProcessor、InstantiationAwareBeanPostProcessor、BeanFactoryPostProcessor 8 * 不需要手动注册 9 * */ 10 applicationContext = new ClassPathXmlApplicationContext("ioc-BeanFactoryPostProcessor.xml") ; 11 } 12 13 @Test 14 public void test(){ 15 Bean bean = applicationContext.getBean("bean", Bean.class) ; 16 RegistryBean registryBean = applicationContext.getBean("registryBean", RegistryBean.class) ; 17 System.out.println(bean); 18 System.out.println("registryBean :" + JSON.toJSONString(registryBean)); 19 } 20 21 @After 22 public void after(){ 23 ((ClassPathXmlApplicationContext)applicationContext).close(); 24 } 25 }
运行结果: 可以看到实现动态的加载 RegistryBean 进入bean容器 和 定制化修改bean definition
修改之前 name 的value是:TypedStringValue: value [zhouxiaoxing], target type [null] Bean{name='postProcessBeanFactory修改属性'} registryBean :{"name":"CustomBeanDefinitionRegistry settings"}
详细demo示例可以参考: https://gitee.com/zhouxiaoxing91/learning-src/tree/master/spring-src/src/main/java/com/nancy/ioc
二、BeanFactoryPostProcessor源码分析:注册时机和触发点
注册和触发的入口在AbstractApplicationContext#refresh 容器刷新阶段, 只会调用一次 属于容器级别的拓展接口:
1 @Override 2 public void refresh() throws BeansException, IllegalStateException { 3 synchronized (this.startupShutdownMonitor) { 4 // Prepare this context for refreshing. 5 prepareRefresh(); 6 7 // Tell the subclass to refresh the internal bean factory. 8 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); 9 10 // Prepare the bean factory for use in this context. 11 prepareBeanFactory(beanFactory); 12 13 try { 14 // Allows post-processing of the bean factory in context subclasses. 15 postProcessBeanFactory(beanFactory); 16 17 // Invoke factory processors registered as beans in the context. 18 // 注册BeanFactoryPostProcessor 在bean definition 加载完成之后 19 invokeBeanFactoryPostProcessors(beanFactory); 20 21 // Register bean processors that intercept bean creation. 22 registerBeanPostProcessors(beanFactory); 23 24 // Initialize message source for this context. 25 initMessageSource(); 26 27 // Initialize event multicaster for this context. 28 initApplicationEventMulticaster(); 29 30 // Initialize other special beans in specific context subclasses. 31 onRefresh(); 32 33 // Check for listener beans and register them. 34 registerListeners(); 35 36 // Instantiate all remaining (non-lazy-init) singletons. 37 finishBeanFactoryInitialization(beanFactory); 38 39 // Last step: publish corresponding event. 40 finishRefresh(); 41 } 42 43 catch (BeansException ex) { 44 if (logger.isWarnEnabled()) { 45 logger.warn("Exception encountered during context initialization - " + 46 "cancelling refresh attempt: " + ex); 47 } 48 49 // Destroy already created singletons to avoid dangling resources. 50 destroyBeans(); 51 52 // Reset 'active' flag. 53 cancelRefresh(ex); 54 55 // Propagate exception to caller. 56 throw ex; 57 } 58 59 finally { 60 // Reset common introspection caches in Spring's core, since we 61 // might not ever need metadata for singleton beans anymore... 62 resetCommonCaches(); 63 } 64 } 65 } 66 67 /** 68 * Instantiate and invoke all registered BeanFactoryPostProcessor beans, 69 * respecting explicit order if given. 70 *Must be called before singleton instantiation.
71 */ 72 protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { 73 PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); 74 75 // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime 76 // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor) 77 if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { 78 beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); 79 beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); 80 } 81 }
这里先说说LoadTimeWeaver(LTW):
在Java 语言中,从织入切面的方式上来看,存在三种织入方式:编译期织入、类加载期织入和运行期织入。编译期织入是指在Java编译期,采用特殊的编译器,将切面织入到Java类中;而类加载期织入则指通过特殊的类加载器,在类字节码加载到JVM时,织入切面;运行期织入则是采用CGLib工具或JDK动态代理进行切面的织入。
AspectJ采用编译期织入和类加载期织入的方式织入切面,是语言级的AOP实现,提供了完备的AOP支持。它用AspectJ语言定义切面,在编译期或类加载期将切面织入到Java类中。
AspectJ提供了两种切面织入方式,第一种通过特殊编译器,在编译期,将AspectJ语言编写的切面类织入到Java类中,可以通过一个Ant或Maven任务来完成这个操作;第二种方式是类加载期织入,也简称为LTW(Load Time Weaving)。
跟进PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors 实例化并触发相关回调:
1 public static void invokeBeanFactoryPostProcessors( 2 ConfigurableListableBeanFactory beanFactory, ListbeanFactoryPostProcessors) { 3 4 // Invoke BeanDefinitionRegistryPostProcessors first, if any. 5 // 优先触发BeanDefinitionRegistryPostProcessor类型bean, 纪录已经触发回调的beanName 6 Set processedBeans = new HashSet (); 7 8 // 1、容器需要具备BeanDefinitionRegistry功能, beanFactoryPostProcessors集合中为容器自身注册的实例, 已知实例集合 9 if (beanFactory instanceof BeanDefinitionRegistry) { 10 BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; 11 List regularPostProcessors = new LinkedList (); 12 List registryProcessors = new LinkedList (); 13 14 // 1.1、优先触发已知实例集合beanFactoryPostProcessors 中 BeanDefinitionRegistryPostProcessor实例 15 for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { 16 if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { 17 BeanDefinitionRegistryPostProcessor registryProcessor = 18 (BeanDefinitionRegistryPostProcessor) postProcessor; 19 registryProcessor.postProcessBeanDefinitionRegistry(registry); 20 registryProcessors.add(registryProcessor); 21 } 22 else { 23 regularPostProcessors.add(postProcessor); 24 } 25 } 26 27 /** 28 * 1.2、 从beanFactory容器中,获取已经加载的BeanDefinitionRegistryPostProcessor实例,并触发回调 29 * 30 * 1.2.1、不会实例化FactoryBeans, 而是留到工厂后置类进行处理. 通过beanFactory.getBeanNamesForType 参数 allowEagerInit 为false控制 31 * 1.2.2、严格遵循顺序, 触发顺序为实现PriorityOrdered->实现Ordered->普通类型接口 32 * 1.2.3、同PriorityOrdered、Ordered则以getOrder()返回值排序, 越小优先级别越高 33 */ 34 // Do not initialize FactoryBeans here: We need to leave all regular beans 35 // uninitialized to let the bean factory post-processors apply to them! 36 // Separate between BeanDefinitionRegistryPostProcessors that implement 37 // PriorityOrdered, Ordered, and the rest. 38 List currentRegistryProcessors = new ArrayList (); 39 40 // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered. 41 String[] postProcessorNames = 42 beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); 43 for (String ppName : postProcessorNames) { 44 if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { 45 currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); 46 // 纪录已触发实例beanName 47 processedBeans.add(ppName); 48 } 49 } 50 sortPostProcessors(currentRegistryProcessors, beanFactory); 51 registryProcessors.addAll(currentRegistryProcessors); 52 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); 53 currentRegistryProcessors.clear(); 54 55 // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered. 56 postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); 57 for (String ppName : postProcessorNames) { 58 if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) { 59 currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); 60 processedBeans.add(ppName); 61 } 62 } 63 sortPostProcessors(currentRegistryProcessors, beanFactory); 64 registryProcessors.addAll(currentRegistryProcessors); 65 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); 66 currentRegistryProcessors.clear(); 67 68 // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear. 69 boolean reiterate = true; 70 while (reiterate) { 71 reiterate = false; 72 postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); 73 for (String ppName : postProcessorNames) { 74 if (!processedBeans.contains(ppName)) { 75 currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); 76 processedBeans.add(ppName); 77 reiterate = true; 78 } 79 } 80 sortPostProcessors(currentRegistryProcessors, beanFactory); 81 registryProcessors.addAll(currentRegistryProcessors); 82 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); 83 currentRegistryProcessors.clear(); 84 } 85 86 // Now, invoke the postProcessBeanFactory callback of all processors handled so far. 87 // 1.3、触发所有BeanDefinitionRegistryPostProcessor实例的 postProcessBeanFactory 回调 88 invokeBeanFactoryPostProcessors(registryProcessors, beanFactory); 89 // 1.4、触发所有BeanFactoryPostProcessor实例的 postProcessBeanFactory 回调 90 invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory); 91 } 92 93 else { 94 // Invoke factory processors registered with the context instance. 95 invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory); 96 } 97 98 /** 99 * 2、 从beanFactory容器中,获取已经加载的BeanFactoryPostProcessor实例,并触发回调 100 * 101 * 2.1、不会实例化FactoryBeans, 而是留到工厂后置类进行处理. 通过beanFactory.getBeanNamesForType 参数 allowEagerInit 为false控制 102 * 2.2、严格遵循顺序, 触发顺序为实现PriorityOrdered->实现Ordered->普通类型接口 103 * 2.3、同PriorityOrdered、Ordered则以getOrder()返回值排序, 越小优先级别越高 104 */ 105 // Do not initialize FactoryBeans here: We need to leave all regular beans 106 // uninitialized to let the bean factory post-processors apply to them! 107 String[] postProcessorNames = 108 beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false); 109 110 // Separate between BeanFactoryPostProcessors that implement PriorityOrdered, 111 // Ordered, and the rest. 112 List priorityOrderedPostProcessors = new ArrayList (); 113 List orderedPostProcessorNames = new ArrayList (); 114 List nonOrderedPostProcessorNames = new ArrayList (); 115 for (String ppName : postProcessorNames) { 116 if (processedBeans.contains(ppName)) { 117 // skip - already processed in first phase above 118 } 119 else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { 120 priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class)); 121 } 122 else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { 123 orderedPostProcessorNames.add(ppName); 124 } 125 else { 126 nonOrderedPostProcessorNames.add(ppName); 127 } 128 } 129 130 // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered. 131 sortPostProcessors(priorityOrderedPostProcessors, beanFactory); 132 invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); 133 134 // Next, invoke the BeanFactoryPostProcessors that implement Ordered. 135 List orderedPostProcessors = new ArrayList (); 136 for (String postProcessorName : orderedPostProcessorNames) { 137 orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); 138 } 139 sortPostProcessors(orderedPostProcessors, beanFactory); 140 invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory); 141 142 // Finally, invoke all other BeanFactoryPostProcessors. 143 List nonOrderedPostProcessors = new ArrayList (); 144 for (String postProcessorName : nonOrderedPostProcessorNames) { 145 nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); 146 } 147 invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory); 148 149 // Clear cached merged bean definitions since the post-processors might have 150 // modified the original metadata, e.g. replacing placeholders in values... 151 beanFactory.clearMetadataCache(); 152 }
对应的触发和排序源码:
![](http://img.e-com-net.com/image/info8/b8d97b5613f94ed2ba791cad57d0b2ed.gif)
![](http://img.e-com-net.com/image/info8/2f88dd3f1cd145f59c0e47b51acdbd4b.gif)
1 private static void sortPostProcessors(List postProcessors, ConfigurableListableBeanFactory beanFactory) { 2 Comparator