spring源码阅读(3)-- 容器启动之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的创建。

原文地址:https://www.cnblogs.com/hanjiehu/p/8671300.html

时间: 2024-08-21 05:39:13

spring源码阅读(3)-- 容器启动之BeanFactoryPostProcessor的相关文章

spring源码:web容器启动(li)

web项目中可以集成spring的ApplicationContext进行bean的管理,这样使用起来bean更加便捷,能够利用到很多spring的特性.我们比较常用的web容器有jetty,tomcat,jboss等,以jetty为例,我们看一下web容器是如何初始化和启动spring的context. 一.Spring容器的加载 在web工程中都有一个web.xml文件,jetty在启动的时候会加载这个配置文件,并且对文件中的各个listener进行加载.ContextLoaderListe

Spring源码分析2 — 容器启动流程

1 主要类 部署web应用时,web容器(比如Tomcat)会读取配置在web.xml中的监听器,从而启动spring容器.有了spring容器之后,我们才能使用spring的IOC AOP等特性.弄清spring容器启动流程,有利于理解spring IOC中的各种特性,比如BeanPostProcessor,MessageSource,ApplicationListener等.我们先来看下容器启动流程中涉及的主要类. ContextLoaderListener:注册在web.xml中,web应

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

在<spring源码阅读(1)-- 容器启动之资源定位>一文中,阅读了spring是怎么根据用户指定的配置加载资源,当加载完资源,接下来便是把从资源中加载BeanDefinition. BeanDefinition作为spring其中一个组件,spring是这样描述BeanDefinition的:BeanDefinition描述了一个bean实例,它具有属性值,构造函数参数值以及具体实现提供的更多信息.个人的理解是BeanDefinition保存了一个bean实例的所有元数据,下面列举一些常用

Spring源码阅读:IOC容器的设计与实现(二)——ApplicationContext

上一主题中,了解了IOC容器的基本概念,以及BeanFactory的设计与实现方式,这里就来了解一下ApplicationContext方式的实现. ApplicationContext 在Spring的参考文档中,为啥要推荐使用ApplicationContext?它能给我们的应用带来什么好处呢?作为BeanFactory的实现之一,它又是如何设计的?在SpringMVC中使用的WebApplictionContext\XmlApplicationContext与之有何关联? Applicat

Spring源码阅读:Spring声明式事务处理和编程式事务处理的设计与实现

之前的学习,了解了Spring事务管理的基础框架(查看).Spring在此基础上又提到了声明式事务管理和编程式事务管理.这里就来看看Spring是如何实现的. Spring声明式事务与EJB事务管理对比 Spring的声明式管理,类似于EJB的CMT,但又有不同.他们的不同之处有: 1)EJB的CMT是与JTA结合使用,而Spring框架的声明式事务管理可以在任何环境下工作.既可以使用全局事务管理,如JTA,也可以使用局部事务管理如JDBCJPA.Hibernate.JDO等. 2)可以在任何类

Spring源码阅读:Spring WebApplicationContext初始化与消亡

使用SpringMVC时,需要不论是使用注解配置,还是使用XML配置Bean,他们都会在Web服务器启动后就初始化.根据J2ee的知识可以知道,肯定是使用了ServletContextListener才完成的这个功能.那Spring又是如何实现的呢?还有我们在Web.xml配置的那些applicationContext.xml相关的XML文件的位置(配置方式多样),又是如何读取到相应的文件的呢,读取到这些文件后,是如何初始化类的呢?我们能不能自定义初始化过程或者自定义WebApplication

Spring源码阅读:Spring MVC 初始化

通过之前的源码学习,了解了Spring的两个核心IOC和AOP.也了解到系统初始化时,就已经将所有applicationContext.xml中的bean Definintion加载并初始化了. 如果使用了SpringMVC框架,MVC框架指定的namespace-servlet.xml也已经被初始化了. 使用过SpringMVC,都知道需要在web.xml配置配置DispatcherServlet,它是处理请求的入口.Servlet是单例的,系统指挥在第一次处理用户请求时初始化Servlet对

Spring源码阅读系列总结

最近一段时间,粗略的查看了一下Spring源码,对Spring的两大核心和Spring的组件有了更深入的了解.同时在学习Spring源码时,得了解一些设计模式,不然阅读源码还是有一定难度的,所以一些重要的设计模式简单的做了阐述.同时还会简单的加入一些GOF中提到的设计原则.Spring的源码阅读系列,也暂告一段落.下面是就带你走进Spring世界: Spring系列的引子 1)Spring WebApplicationContext初始化与消亡 这一节帮我们了解Spring是如何初始化WebAp

Spring源码阅读:Spring MVC 如何处理HTTP请求

Spring MVC 对HTTP请求的处理流程 通过之前的源码阅读,知道了ApplicationContext初始的过程,也知道了Spring MVC环境的初始化过程,今天就来了解一下SpringMVC是如何处理HTTP请求的. HTTP请求根据请求方式可以分为GET.POST.PUT.DELETE.OPTIONS.TRACE,最常用的还是GET和POST. Spring对于这几种HTTP请求的处理都是使用了processRequest(req,rep); @Override protected