spring源码阅读-- 容器启动之BeanFactoryPostProcessor

Posted hanjiehu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring源码阅读-- 容器启动之BeanFactoryPostProcessor相关的知识,希望对你有一定的参考价值。

  接着上文《spring源码阅读(2)-- 容器启动之加载BeanDefinition》,当spring加载完所有BeanDefinition时,并不会马上去创建bean,而是先配置beanFactory,例如设置一下装配规则和判断是否需要创建一些指定的bean。

 1   protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
 2         // Tell the internal bean factory to use the context‘s class loader etc.
 3         beanFactory.setBeanClassLoader(getClassLoader());
 4         beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
 5         beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
 6 
 7         // Configure the bean factory with context callbacks.
 8         //添加ApplicationContextAwareProcessor用于处理实现了EnvironmentAware、EmbeddedValueResolverAware、ApplicationContextAware接口的bean
 9         beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
10         //忽略以下bean的依赖注入
11         beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
12         beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
13         beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
14         beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
15         beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
16 
17         // BeanFactory interface not registered as resolvable type in a plain factory.
18         // MessageSource registered (and found for autowiring) as a bean.
19         //注册自动装配模式下的特殊依赖,例如被注入的是BeanFactory类型,那么注入的就是beanFactory
20         beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
21         beanFactory.registerResolvableDependency(ResourceLoader.class, this);
22         beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
23         beanFactory.registerResolvableDependency(ApplicationContext.class, this);
24 
25         // Detect a LoadTimeWeaver and prepare for weaving, if found.
26         if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
27             beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
28             // Set a temporary ClassLoader for type matching.
29             beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
30         }
31 
32         // Register default environment beans.
33         if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
34             beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
35         }
36         if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
37             beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
38         }
39         if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
40             beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
41         }
42     }

  当设置完beanFactory,接下来就是执行BeanFactoryPostProcessor。BeanFactoryPostProcessor是spring容器启动时暴露给用户的一个扩展点,允许用户在spring创建bean之前做修改或动态添加bean,动态注册bean可以使用BeanFactoryPostProcessor的子类BeanDefinitionRegistryPostProcessor。BeanFactoryPostProcessor接口定义如下:

1  public interface BeanFactoryPostProcessor {
2 
3     void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
4 
5 }

  当我们实现了BeanFactoryPostProcessor,spring是怎么去执行的呢?

  spring容器在执行刷新时,当加载完BeanDefinition和配置好beanFactory时,会进入AbstractApplicationContext.invokeBeanFactoryPostProcessors,方法里首先调用PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors去执行实现了BeanFactoryPostProcessor的postProcessBeanFactory方法,然后再判断是否新添加了loadTimeWeaver这个bean,如果有,添加LoadTimeWeaverAwareProcessor

 1     protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
 2         PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
 3 
 4         // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
 5         // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
 6         if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
 7             beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
 8             beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
 9         }
10     }

 

  进入PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors方法,方法里首先判断beanFactory是不是一个bean注册中心,如果是,循环遍历传入的BeanFactoryPostProcessor,判断是否是BeanDefinitionRegistryPostProcessor的实现,如果是,执行BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry,然后保存到一个集合用于在执行完所有的BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry方法之后,再执行BeanFactoryPostProcessor.postProcessBeanFactory。

  1     public static void invokeBeanFactoryPostProcessors(
  2             ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
  3 
  4         // Invoke BeanDefinitionRegistryPostProcessors first, if any.
  5         Set<String> processedBeans = new HashSet<String>();
  6 
  7         if (beanFactory instanceof BeanDefinitionRegistry) {
  8             BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
  9             List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
 10             List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
 11                     new LinkedList<BeanDefinitionRegistryPostProcessor>();
 12 
 13             for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
 14                 if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
 15                     BeanDefinitionRegistryPostProcessor registryPostProcessor =
 16                             (BeanDefinitionRegistryPostProcessor) postProcessor;
 17                     registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
 18                     registryPostProcessors.add(registryPostProcessor);
 19                 }
 20                 else {
 21                     regularPostProcessors.add(postProcessor);
 22                 }
 23             }
 24 
 25             // Do not initialize FactoryBeans here: We need to leave all regular beans
 26             // uninitialized to let the bean factory post-processors apply to them!
 27             // Separate between BeanDefinitionRegistryPostProcessors that implement
 28             // PriorityOrdered, Ordered, and the rest.
 29             String[] postProcessorNames =
 30                     beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
 31 
 32             // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
 33             List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
 34             for (String ppName : postProcessorNames) {
 35                 if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
 36                     priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
 37                     processedBeans.add(ppName);
 38                 }
 39             }
 40             sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
 41             registryPostProcessors.addAll(priorityOrderedPostProcessors);
 42             invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);
 43 
 44             // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
 45             postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
 46             List<BeanDefinitionRegistryPostProcessor> orderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
 47             for (String ppName : postProcessorNames) {
 48                 if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
 49                     orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
 50                     processedBeans.add(ppName);
 51                 }
 52             }
 53             sortPostProcessors(beanFactory, orderedPostProcessors);
 54             registryPostProcessors.addAll(orderedPostProcessors);
 55             invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry);
 56 
 57             // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
 58             boolean reiterate = true;
 59             while (reiterate) {
 60                 reiterate = false;
 61                 postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
 62                 for (String ppName : postProcessorNames) {
 63                     if (!processedBeans.contains(ppName)) {
 64                         BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);
 65                         registryPostProcessors.add(pp);
 66                         processedBeans.add(ppName);
 67                         pp.postProcessBeanDefinitionRegistry(registry);
 68                         reiterate = true;
 69                     }
 70                 }
 71             }
 72 
 73             // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
 74             invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
 75             invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
 76         }
 77 
 78         else {
 79             // Invoke factory processors registered with the context instance.
 80             invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
 81         }
 82 
 83         // Do not initialize FactoryBeans here: We need to leave all regular beans
 84         // uninitialized to let the bean factory post-processors apply to them!
 85         String[] postProcessorNames =
 86                 beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
 87 
 88         // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
 89         // Ordered, and the rest.
 90         List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
 91         List<String> orderedPostProcessorNames = new ArrayList<String>();
 92         List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
 93         for (String ppName : postProcessorNames) {
 94             if (processedBeans.contains(ppName)) {
 95                 // skip - already processed in first phase above
 96             }
 97             else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
 98                 priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
 99             }
100             else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
101                 orderedPostProcessorNames.add(ppName);
102             }
103             else {
104                 nonOrderedPostProcessorNames.add(ppName);
105             }
106         }
107 
108         // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
109         sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
110         invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
111 
112         // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
113         List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
114         for (String postProcessorName : orderedPostProcessorNames) {
115             orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
116         }
117         sortPostProcessors(beanFactory, orderedPostProcessors);
118         invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
119 
120         // Finally, invoke all other BeanFactoryPostProcessors.
121         List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
122         for (String postProcessorName : nonOrderedPostProcessorNames) {
123             nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
124         }
125         invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
126 
127         // Clear cached merged bean definitions since the post-processors might have
128         // modified the original metadata, e.g. replacing placeholders in values...
129         beanFactory.clearMetadataCache();
130     }

  invokeBeanFactoryPostProcessors方法里会找出所有的bean,先排序然后再执行相应的方法。从源码可以看得出,先执行的是传进来的BeanFactoryPostProcessor,第二是实现了PriorityOrdered的接口,第三是实现了Ordered接口,最后的就是没有指定顺序的,而实现了BeanDefinitionRegistryPostProcessor的,会先执行BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry。

  至此,spring对BeanFactoryPostProcessor的扩展点已处理完,从源码可以开出,BeanFactoryPostProcessor的处理会触发bean的创建。

以上是关于spring源码阅读-- 容器启动之BeanFactoryPostProcessor的主要内容,如果未能解决你的问题,请参考以下文章

spring源码阅读-- 容器启动之加载BeanDefinition

Spring源码阅读之Springs-beans容器的基本实现

Spring源码阅读Spring容器启动原理(上)-配置资源加载和注册

Spring源码阅读Spring容器启动原理(下)-Bean实例的创建和依赖注入

Spring源码分析专题——目录

头秃系列,二十三张图带你从源码分析Spring Boot 启动流程~