spring源码分析系列 (1) spring拓展接口BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor

更多文章点击--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示例:

 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 }
CustomBeanDefinitionRegistry.java
 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 }
LogicBeanFactoryPostProcessor.java
 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 }
RegistryBean.java
 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>
ioc-BeanFactoryPostProcessor.xml
 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 }
BeanFactoryPostProcessorTest.java

 运行结果: 可以看到实现动态的加载 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      * <p>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, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
  3 
  4         // Invoke BeanDefinitionRegistryPostProcessors first, if any.
  5         // 优先触发BeanDefinitionRegistryPostProcessor类型bean, 纪录已经触发回调的beanName
  6         Set<String> processedBeans = new HashSet<String>();
  7 
  8         // 1、容器需要具备BeanDefinitionRegistry功能, beanFactoryPostProcessors集合中为容器自身注册的实例, 已知实例集合
  9         if (beanFactory instanceof BeanDefinitionRegistry) {
 10             BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
 11             List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
 12             List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList<BeanDefinitionRegistryPostProcessor>();
 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<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
 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<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
113         List<String> orderedPostProcessorNames = new ArrayList<String>();
114         List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
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<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
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<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
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     }

 对应的触发和排序源码:

 1 private static void sortPostProcessors(List<?> postProcessors, ConfigurableListableBeanFactory beanFactory) {
 2         Comparator<Object> comparatorToUse = null;
 3         if (beanFactory instanceof DefaultListableBeanFactory) {
 4             comparatorToUse = ((DefaultListableBeanFactory) beanFactory).getDependencyComparator();
 5         }
 6         if (comparatorToUse == null) {
 7             comparatorToUse = OrderComparator.INSTANCE;
 8         }
 9         postProcessors.sort(comparatorToUse);
10     }
11 
12     /**
13      * Invoke the given BeanDefinitionRegistryPostProcessor beans.
14      */
15     private static void invokeBeanDefinitionRegistryPostProcessors(
16             Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
17 
18         for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
19             postProcessor.postProcessBeanDefinitionRegistry(registry);
20         }
21     }
22 
23     /**
24      * Invoke the given BeanFactoryPostProcessor beans.
25      */
26     private static void invokeBeanFactoryPostProcessors(
27             Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
28 
29         for (BeanFactoryPostProcessor postProcessor : postProcessors) {
30             postProcessor.postProcessBeanFactory(beanFactory);
31         }
32     }
View Code

 

posted on 2019-01-29 11:27  小猩  阅读(2763)  评论(0编辑  收藏  举报

导航