在上一章中笔者介绍了refresh()的<1>处是如何获取beanFactory对象,下面咱们要来学习refresh()方法的<2>处是如何调用invokeBeanFactoryPostProcessors方法执行bean工厂后置处理器,这个方法在笔者看来是整个refresh()方法最重要的方法之一,由于就是在这个方法完成了扫描类路径下全部的类,并将类解析成BeanDefinition注册到spring容器中。html
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext { …… @Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { …… // Tell the subclass to refresh the internal bean factory. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();//<1> …… try { …… // Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory);//<2> …… } catch (BeansException ex) { …… } finally { …… } } } …… }
在了解invokeBeanFactoryPostProcessors(beanFactory)方法的运做原理前,咱们须要对spring的两个接口有一个基本的认识:BeanFactoryPostProcessor(bean工厂后置处理器)、BeanDefinitionRegistryPostProcessor(bean定义注册后置处理器)。java
public interface BeanFactoryPostProcessor { void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException; } public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor { void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException; }
若是有看过笔者先前写的Spring源码解析之BeanFactoryPostProcessor(一)应该对BeanFactoryPostProcessor有印象,在这一章节中笔者说过BeanFactoryPostProcessor接口实现类的执行时机是在扫描完全部BeanDefinition并注册到spring容器以后,以及实例化bean以前。这一章笔者也建立了一个BeanFactoryPostProcessor接口的实现类Test1BeanFactoryPostProcessor,在postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)方法中笔者将userService的beanDefinition的class替换成OrderService.class,当咱们从spring容器获取userService对应的bean,bean的类型为OrderService而不是UserService。程序员
那么笔者不由有个疑问,spring又是如何根据程序员指定的类路径将路径下的类解析成BeanDefinition并注册进spring容器呢?答案就在BeanDefinitionRegistryPostProcessor。根据spring官方文档介绍:BeanDefinitionRegistryPostProcessor接口的做用就是向spring容器注册BeanDefinition,且BeanDefinitionRegistryPostProcessor的执行时机在BeanFactoryPostProcessor以前,而BeanFactoryPostProcessor的做用更倾向于在spring容器获取到全部BeanDefinition后,在实例化bean以前,修改BeanDefinition的属性。好比设定链接池的最大链接数不能超过1000,咱们就能够在BeanFactoryPostProcessor获取链接池BeanDefinition的最大链接数,若是超过一千则将最大链接数改成1000。又或者咱们提供了一个聊天服务接口ChatService,并实现了一个与之同名的实现类,假设这个实现类是基于MySQL实现的一个聊天服务,后续咱们又开发了一个基于Redis的聊天服务实现类ChatService2,当外部须要依赖注入ChatService接口时咱们更但愿注入的是基于Redis实现的ChatService2聊天服务而不是原先基于MySQL实现的ChatService,也能够实现一个BeanFactoryPostProcessor,并将chatService的BeanDefinition的class替换成ChatService2。spring
在Spring源码解析之BeanFactoryPostProcessor(一)讲述AnnotatedBeanDefinitionReader的时候,笔者曾说过这个类的构造方法会执行到AnnotationConfigUtils.registerAnnotationConfigProcessors(...),在这个方法内会注册一些基础组件的BeanDefinition注册进spring容器中。当时笔者说过其中一个基础组件:ConfigurationClassPostProcessor就是完成BeanDefinition扫描的工做,而ConfigurationClassPostProcessor这个类就实现了BeanDefinitionRegistryPostProcessor,在postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)方法中扫描出配置类指定路径下全部的类,并筛选出那些能够成为BeanDefinition的类注册到spring容器中。bash
此外,BeanDefinitionRegistryPostProcessor的父类是BeanFactoryPostProcessor,从某个角度上来看:BeanDefinitionRegistryPostProcessor接口的实现也能够看做是BeanFactoryPostProcessor。所以refresh()方法中调用的invokeBeanFactoryPostProcessors(beanFactory),除了执行BeanFactoryPostProcessor的实现类,还会执行BeanDefinitionRegistryPostProcessor的实现类,并且BeanDefinitionRegistryPostProcessor实现类的执行时机会先于BeanFactoryPostProcessor的实现类。mybatis
当调用invokeBeanFactoryPostProcessors(beanFactory)方法时,会进而执行到PostProcessorRegistrationDelegate类的静态方法invokeBeanFactoryPostProcessors(...),这个方法接收一个beanFactory和BeanFactoryPostProcessor列表。app
在下面的代码<1>处,会先判断传入的beanFactory对象可否转型成BeanDefinitionRegistry,在Spring源码解析之BeanFactoryPostProcessor(二)章节中笔者曾介绍这针对注解(AnnotationConfigApplicationContext)和XML(ClassPathXmlApplicationContext)应用上下文spring各开发了两个父类GenericApplicationContext和AbstractRefreshableApplicationContext来获取beanFactory,这两个父类的beanFactory对象类型为DefaultListableBeanFactory,DefaultListableBeanFactory类既是ConfigurableListableBeanFactory接口的实现类,也是BeanDefinitionRegistry接口的实现类,因此大部分状况下会进入<1>处的分支。由于一般咱们启动spring容器不是经过注解就是经过XML初始化应用上下文,而注解和XML应用上下文返回的beanFactory类型实际上都是DefaultListableBeanFactory,除非是重写refreshBeanFactory()、获取getBeanFactory()这两个方法,那么能够自定义一个BeanFactory的实现类且不实现ConfigurableListableBeanFactory接口,也就不会进到分支<1>。框架
在进入到<1>处的分支后会循环beanFactoryPostProcessors列表,若是列表内的元素能够转型成BeanDefinitionRegistryPostProcessor,则执行元素实现的的postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)方法,将元素添加到registryProcessors列表,若是不能转型则添加到regularPostProcessors列表,到达必定时机,spring会执行registryProcessors和regularPostProcessors两个列表中元素实现的postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)。这里也印证了spring官方文档所说的BeanDefinitionRegistryPostProcessor实现类会优先于BeanFactoryPostProcessor实现类执行。ide
此外,这里咱们也注意到参数beanFactoryPostProcessors是由AbstractApplicationContext调用getBeanFactoryPostProcessors()方法传入的,getBeanFactoryPostProcessors()会返回beanFactoryPostProcessors这个列表,beanFactoryPostProcessors默认为一个空列表,咱们能够调用addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor)将本身建立的bean工厂后置处理器对象添加到beanFactoryPostProcessors这个列表。所以,在执行invokeBeanFactoryPostProcessors(...)最初会先执行由程序员建立的BeanDefinitionRegistryPostProcessor对象。spring-boot
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext { …… private final List<BeanFactoryPostProcessor> beanFactoryPostProcessors = new ArrayList<>(); …… @Override public void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor) { Assert.notNull(postProcessor, "BeanFactoryPostProcessor must not be null"); this.beanFactoryPostProcessors.add(postProcessor); } public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() { return this.beanFactoryPostProcessors; } …… protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); …… } …… } final class PostProcessorRegistrationDelegate { …… public static void invokeBeanFactoryPostProcessors( ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { // Invoke BeanDefinitionRegistryPostProcessors first, if any. Set<String> processedBeans = new HashSet<>(); if (beanFactory instanceof BeanDefinitionRegistry) {//<1> BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>(); List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>(); for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor; registryProcessor.postProcessBeanDefinitionRegistry(registry); registryProcessors.add(registryProcessor); } else { regularPostProcessors.add(postProcessor); } } …… } else { // Invoke factory processors registered with the context instance. invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory); } …… } …… }
这里咱们建立一个bean工厂后置处理器(BeanFactoryPostProcessor)和BeanDefinition注册后置处理器(BeanDefinitionRegistryPostProcessor)的实现类,并建立者两个类的实例添加到上下文对象而后看看两个实现类实现的接口的回调时机。
Test3BeanDefinitionRegistryPostProcessor.java
package org.example.beanFactoryPostProcessor; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; public class Test2BeanFactoryPostProcessor implements BeanFactoryPostProcessor { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { System.out.println("test2 postProcessBeanFactory..."); } }
Test3BeanDefinitionRegistryPostProcessor.java
package org.example.beanFactoryPostProcessor; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; public class Test3BeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor { @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { System.out.println("test3 postProcessBeanDefinitionRegistry..."); } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { System.out.println("test3 postProcessBeanFactory..."); } }
测试用例:
@Test public void test05() { AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(); ac.addBeanFactoryPostProcessor(new Test2BeanFactoryPostProcessor()); ac.addBeanFactoryPostProcessor(new Test3BeanDefinitionRegistryPostProcessor()); ac.refresh(); }
打印结果:
test3 postProcessBeanDefinitionRegistry... test3 postProcessBeanFactory... test2 postProcessBeanFactory...
能够看到spring会优先执行BeanDefinitionRegistryPostProcessor实现类的postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)方法,再执行BeanDefinitionRegistryPostProcessor实现类的postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)方法,最后才执行BeanFactoryPostProcessor实现类的postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)方法。
须要注意一点的是:spring有两种提供bean工厂后置处理器(BeanFactoryPostProcessor )的方式:
这两种方式不一样点是:前者是程序员手动建立bean工厂后置处理器对象再交由spring执行,但这个对象自己不是一个bean,这个对象虽然实现了spring的接口,但它的生命周期不归spring管理;后者是bean工厂后置处理器对象的建立由spring负责,这个对象在spring容器中是一个bean,spring一样会这个bean的回调方法,这个bean的生命周期由spring管理。
上面这两种提供方式一样适用于BeanDefinition注册后置处理器(BeanDefinitionRegistryPostProcessor),由于BeanDefinitionRegistryPostProcessor自己就能够当作是一个BeanDefinitionRegistryPostProcessor。
标记了@Component注解的BeanFactoryPostProcessor实现类,它的bean对象不在AbstractApplicationContext类的beanFactoryPostProcessors列表中。换句话说beanFactoryPostProcessors列表的元素必须手动建立对象并添加,假设咱们开发了两个BeanDefinitionRegistryPostProcessor的实现类:FooBeanDefinitionRegistryPostProcessor和BarBeanDefinitionRegistryPostProcessor,FooBeanDefinitionRegistryPostProcessor是用过手动建立对象添加到beanFactoryPostProcessors列表,BarBeanDefinitionRegistryPostProcessor是经过@Component注解由spring建立bean对象。下面代码<1>处遍历beanFactoryPostProcessors列表中只有一个FooBeanDefinitionRegistryPostProcessor对象会获得执行,而BarBeanDefinitionRegistryPostProcessor对应的bean会在后面的代码进行接口回调,但不会在<1>处进行回调。
final class PostProcessorRegistrationDelegate { …… public static void invokeBeanFactoryPostProcessors( ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { // Invoke BeanDefinitionRegistryPostProcessors first, if any. Set<String> processedBeans = new HashSet<>(); if (beanFactory instanceof BeanDefinitionRegistry) { BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>(); List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>(); for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {//<1> if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor; registryProcessor.postProcessBeanDefinitionRegistry(registry); registryProcessors.add(registryProcessor); } else { regularPostProcessors.add(postProcessor); } } …… } …… } …… }
咱们来对比下下面18~2九、32~42这两段代码,这两段代码完成的工做是极其类似的,会遍历全部已经注册到spring容器的BeanDefinition,找出BeanDefinitionRegistryPostProcessor实现类对应的beanName并将其返回。以后会在<1>、<2>处判断这个beanName对应的class在实现了BeanDefinitionRegistryPostProcessor接口的前提下,是否分别实现了PriorityOrdered、Ordered接口。
Ordered是PriorityOrdered的父接口,PriorityOrdered自己并无实现任何方法,而是直接继承Ordered,实现了PriorityOrdered的类会优先于实现了Ordered的类执行。Ordered接口会要求实现类返回一个数值用于排序,返回数值越小的实现类排在越前。以后这两段代码都会从bean工厂根据beanName和类型获取BeanDefinitionRegistryPostProcessor实现类的bean对象,并将待执行的bean对象加到currentRegistryProcessors列表,将对应的beanName加入到processedBeans表示已经处理这个bean,再对currentRegistryProcessors列表进行排序,这里就会用到Ordered接口要求返回的数值,越小排越前,即返回数值越小越优先执行。
排序完毕后会将currentRegistryProcessors列表的元素加入到registryProcessors列表,而后调用invokeBeanDefinitionRegistryPostProcessors(...)方法遍历currentRegistryProcessors列表每一个对象,执行其实现的postProcessBeanDefinitionRegistry(...)方法,开始真正处理列表中每个bean对象,处理完毕后再清空currentRegistryProcessors列表。而registryProcessors列表在将来的某个时机,会执行列表中全部对象实现的postProcessBeanFactory(...)方法。
须要注意一点:第一段代码会找出全部实现了BeanDefinitionRegistryPostProcessor和PriorityOrdered接口的实现类,将其beanName加入到processedBeans表示这个bean已经处理,即使这个时候还没有执行bean对象的postProcessBeanDefinitionRegistry(...)方法,但后续会执行。第二段代码在找出BeanDefinitionRegistryPostProcessor和Ordered接口实现类的同事,也会找到第一段代码已经找到的实现类,由于PriorityOrdered是Ordered的子接口,意味着实现了PriorityOrdered一样实现了Ordered,但这里不会出现重复执行同一个bean对象的的postProcessBeanDefinitionRegistry(...)方法,由于在第二段代码会再判断beanName是否在processedBeans中,只有不在processedBeans集合的beanName才容许执行,若是beanName已经在processedBeans,代表这个bean在以前已经执行了postProcessBeanDefinitionRegistry(...)方法。currentRegistryProcessors列表在这两段代码都只会存放还没有执行的BeanDefinitionRegistryPostProcessor实现类,而且在这两段代码执行完毕后都会清空currentRegistryProcessors列表,因此咱们也不用担忧registryProcessors列表会存在相同的bean对象。
这里还能够和你们先剧透一下,先前咱们介绍的在构造AnnotatedBeanDefinitionReader对象时会将一些基础组件以BeanDefinition的形式注册到spring容器中待后续spring容器根据BeanDefinition构造bean,其中一个基础组件ConfigurationClassPostProcessor就会在下面第一段代码(即18~29行)执行,ConfigurationClassPostProcessor为BeanDefinitionRegistryPostProcessor和PriorityOrdered两个接口的实现类,在执行这个实现类的postProcessBeanDefinitionRegistry(...)方法时,就会扫描配置类指定的类路径,并筛选类路径下能够成为BeanDefinition的类注册进spring容器,供后续spring根据BeanDefinition构造bean。ConfigurationClassPostProcessor是如何完成BeanDefinition的筛选和注册后续笔者还会讲解,这里咱们只要知道第一段代码会完成类路径的扫描便可。
final class PostProcessorRegistrationDelegate { …… public static void invokeBeanFactoryPostProcessors( ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { // Invoke BeanDefinitionRegistryPostProcessors first, if any. Set<String> processedBeans = new HashSet<>(); if (beanFactory instanceof BeanDefinitionRegistry) { …… // Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let the bean factory post-processors apply to them! // Separate between BeanDefinitionRegistryPostProcessors that implement // PriorityOrdered, Ordered, and the rest. List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>(); // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered. String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {//<1> currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered. postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {//<2> currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); …… } …… } …… }
BeanDefinitionRegistryPostProcessor接口是spring较为底层的接口,spring-context包下也只有ConfigurationClassPostProcessor实现了BeanDefinitionRegistryPostProcessor接口,除了ConfigurationClassPostProcessor类以外spring家族再无BeanDefinitionRegistryPostProcessor接口的实现。此外就笔者目前所见的开源框架,除了spring-context、spring-boot外,也只有mybatis集成spring的包(mybatis-spring)实现了BeanDefinitionRegistryPostProcessor接口,即:org.mybatis.spring.mapper.MapperScannerConfigurer,不过MapperScannerConfigurer类并无实现PriorityOrdered和Ordered的接口,因此MapperScannerConfigurer并不会再上面的代码执行,而是会在后续的某个时机执行。
在前后执行完实现了PriorityOrdered和Ordered接口的BeanDefinitionRegistryPostProcessor实现类,会用一个while循环不断从bean工厂获取还没有执行的BeanDefinitionRegistryPostProcessor实现类,由于可能存在spring在执行一个BeanDefinitionRegistryPostProcessor实现类的postProcessBeanDefinitionRegistry(...)方法时有新的BeanDefinitionRegistryPostProcessor类以BeanDefinition的形式注册进bean工厂。每次循环都会把还没有执行的BeanDefinitionRegistryPostProcessor实现类加入到registryProcessors列表,直到获取不到还没有执行的BeanDefinitionRegistryPostProcessor实现类才会退出循环,而咱们以前所说的MapperScannerConfigurer类也就是在下面的while循环执行的,退出while循环后统一执行registryProcessors和regularPostProcessors列表中对象实现的postProcessBeanFactory(...)。
已经找到整个项目中全部的BeanDefinitionRegistryPostProcessor对象,这个列表的顺序会优先存储程序员手动建立的BeanDefinitionRegistryPostProcessor对象,再存储实现了PriorityOrdered和Ordered接口的BeanDefinitionRegistryPostProcessor对象,,不论是内置的亦或是集成别的项目或是程序员本身开发的BeanDefinitionRegistryPostProcessor实现类,都会存到,和regularPostProcessors两个列表中对象实现的postProcessBeanFactory(...)方法。
final class PostProcessorRegistrationDelegate { …… public static void invokeBeanFactoryPostProcessors( ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { // Invoke BeanDefinitionRegistryPostProcessors first, if any. Set<String> processedBeans = new HashSet<>();
if (beanFactory instanceof BeanDefinitionRegistry) { …… // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear. boolean reiterate = true; while (reiterate) { reiterate = false; postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { if (!processedBeans.contains(ppName)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); reiterate = true; } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); } // Now, invoke the postProcessBeanFactory callback of all processors handled so far. invokeBeanFactoryPostProcessors(registryProcessors, beanFactory); invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory); } …… } …… }
若是beanFactory能够转型成BeanDefinitionRegistry,则会进入分支<1>,而在分支<1>内部会作的工做咱们也已经了解。若是beanFactory不能转型成BeanDefinitionRegistry,则会进入分支<2>,这里就会执行咱们手动建立的BeanFactoryPostProcessor对象的postProcessBeanFactory(...)方法。但就笔者目前的开发经验,大部分状况下都会进入分支<1>,会进入分支<2>的状况笔者至今还未见过,但愿有这方面业务经验的同窗能够不吝赐教。
在执行分支<1>或分支<2>的代码后,会获取spring容器内全部BeanFactoryPostProcessor实现类对应的beanName,这里依旧可能把以前已经处理过的beanName获取出来。在遍历这些beanName的时候若是判断已经在processedBeans集合中,则表示已经处理过,这里就会跳过这个beanName,若是是不在processedBeans集合,则会根据是否实现PriorityOrdered、Ordered接口和都没实现分为三组,会分别对实现了PriorityOrdered和Ordered接口的bean工厂处理器进行排序,再分组执行,最后执行没有实现PriorityOrdered和Ordered接口的bean工厂后置处理器。
final class PostProcessorRegistrationDelegate { …… public static void invokeBeanFactoryPostProcessors( ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { // Invoke BeanDefinitionRegistryPostProcessors first, if any. Set<String> processedBeans = new HashSet<>(); if (beanFactory instanceof BeanDefinitionRegistry) {//<1> …… } else {//<2> // Invoke factory processors registered with the context instance. invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory); } // Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let the bean factory post-processors apply to them! String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false); // Separate between BeanFactoryPostProcessors that implement PriorityOrdered, // Ordered, and the rest. List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>(); List<String> orderedPostProcessorNames = new ArrayList<>(); List<String> nonOrderedPostProcessorNames = new ArrayList<>(); for (String ppName : postProcessorNames) { if (processedBeans.contains(ppName)) { // skip - already processed in first phase above } else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class)); } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { orderedPostProcessorNames.add(ppName); } else { nonOrderedPostProcessorNames.add(ppName); } } // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered. sortPostProcessors(priorityOrderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); // Next, invoke the BeanFactoryPostProcessors that implement Ordered. List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size()); for (String postProcessorName : orderedPostProcessorNames) { orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } sortPostProcessors(orderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory); // Finally, invoke all other BeanFactoryPostProcessors. List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size()); for (String postProcessorName : nonOrderedPostProcessorNames) { nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory); // Clear cached merged bean definitions since the post-processors might have // modified the original metadata, e.g. replacing placeholders in values... beanFactory.clearMetadataCache(); } …… }
下面咱们来看看PriorityOrdered和Ordered两个接口,正如笔者所言, PriorityOrdered接口自己并无要求实现任何方法,PriorityOrdered接口的设计只是为了和Ordered作一个区分,子接口会优先执行,父接口会在子接口执行完毕后才执行。这两个接口都会要求实现类在getOrder()方法返回一个数值,数值越小排序越前。
public interface PriorityOrdered extends Ordered { } public interface Ordered { int HIGHEST_PRECEDENCE = Integer.MIN_VALUE; int LOWEST_PRECEDENCE = Integer.MAX_VALUE; int getOrder(); }
最后,咱们总结下PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(...)整个方法的流程就结束本章的讲解。这个方法接收一个beanFactory对象,和beanFactoryPostProcessors列表。一般状况下:beanFactoryPostProcessors列表是程序员手动建立的BeanFactoryPostProcessor对象,beanFactory能够转型成BeanDefinitionRegistry,因此会进入下面代码<1>处的分支。在分支<1>内部会建立两个列表regularPostProcessors和registryProcessors,这里会遍历beanFactoryPostProcessors列表,判断列表中每一个对象是否能转型成BeanDefinitionRegistryPostProcessor接口,若是转型成功则执行其实现的postProcessBeanDefinitionRegistry(...)方法并将对象存放到registryProcessors列表,转型失败则存放在regularPostProcessors列表。
以后在代码的33~44行会获取已经以BeanDefinition形式存放到spring容器内BeanDefinitionRegistryPostProcessor实现类对应的beanName,并判断beanName对应的BeanDefinitionRegistryPostProcessor实现类是否也实现了PriorityOrdered,实现了PriorityOrdered接口则会进入<2>处的分支,从bean工厂根据beanName获取对应的bean对象并加入到currentRegistryProcessors列表,以后会将currentRegistryProcessors列表进行排序,将列表中的元素添加到registryProcessors,执行currentRegistryProcessors列表全部对象实现的postProcessBeanDefinitionRegistry(...)方法,再清空currentRegistryProcessors列表。而在33~44行也会执行BeanDefinitionRegistryPostProcessor的实现类ConfigurationClassPostProcessor,在这个实现类的postProcessBeanDefinitionRegistry(...)方法中完成类路径的扫描,解析类路径下能够成为BeanDefinition的类并将其注册到spring容器中。
代码47~57行和33~44太过类似,不一样的是后者执行的是一样实现了Ordered接口的BeanDefinitionRegistryPostProcessor实现类,因为PriorityOrdered是Ordered的子接口,这里会把33~44行已经执行过的beanName找出来,但这些已经执行过的beanName已经存放在processedBeans集合,因此这里会过滤掉,只会执行还没有执行的Ordered和BeanDefinitionRegistryPostProcessor的实现类。
在代码<4>处会有一个while循环,不断去遍历spring容器内现有BeanDefinitionRegistryPostProcessor实现类对应的beanName,这里一样会把以前已经找到的beanName获取出来,一样会用processedBeans集合过滤已经处理过的beanName,只会执行还没有执行的BeanDefinitionRegistryPostProcessor实现类的bean对象。等到肯定spring容器内再也不有还没有执行的BeanDefinitionRegistryPostProcessor实现类就会退出while循环。此时registryProcessors已经拥有了程序员手动建立的BeanDefinitionRegistryPostProcessor对象和整个spring容器全部的BeanDefinitionRegistryPostProcessor实现类的bean对象,在<5>处会执行这些BeanDefinitionRegistryPostProcessor对象的postProcessBeanFactory(...)方法,再执行程序员手动建立的BeanFactoryPostProcessor对象的postProcessBeanFactory(...)方法,至此完成分支<1>的全部工做,全部的BeanDefinitionRegistryPostProcessor对象都前后完成了postProcessBeanDefinitionRegistry(...)和postProcessBeanFactory(...)方法的调用。
以后会获取spring容器内全部BeanFactoryPostProcessor实现类对应的beanName,这里会遍历这些beanName,若是已经存在processedBeans集合的beanName表明已经处理过,这里会跳过已经处理过的beanName,收集实现了PriorityOrdered或Ordered接口,和这两个接口都没实现的BeanFactoryPostProcessor实现类的bean对象,这里会优先对实现了PriorityOrdered接口的BeanFactoryPostProcessor对象进行排序并执行postProcessBeanFactory(...)方法,再对实现了Ordered接口的BeanFactoryPostProcessor对象进行排序再执行postProcessBeanFactory(...)方法,最后是执行没有实现PriorityOrdered或Ordered接口的BeanFactoryPostProcessor对象的postProcessBeanFactory(...)方法。
这里也再次证明了spring对BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor两个接口的定义:BeanDefinitionRegistryPostProcessor的实现会优先于BeanFactoryPostProcessor执行,而BeanDefinitionRegistryPostProcessor实现的postProcessBeanDefinitionRegistry(...)也会优先自己实现的postProcessBeanFactory(...)执行,最后才执行仅实现了BeanFactoryPostProcessor接口的postProcessBeanFactory(...)方法。
final class PostProcessorRegistrationDelegate { …… public static void invokeBeanFactoryPostProcessors( ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { // Invoke BeanDefinitionRegistryPostProcessors first, if any. Set<String> processedBeans = new HashSet<>(); if (beanFactory instanceof BeanDefinitionRegistry) {//<1> BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>(); List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>(); for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor; registryProcessor.postProcessBeanDefinitionRegistry(registry); registryProcessors.add(registryProcessor); } else { regularPostProcessors.add(postProcessor); } } // Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let the bean factory post-processors apply to them! // Separate between BeanDefinitionRegistryPostProcessors that implement // PriorityOrdered, Ordered, and the rest. List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>(); // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered. String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {//<2> currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered. postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {//<3> currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear. boolean reiterate = true; while (reiterate) {//<4> reiterate = false; postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { if (!processedBeans.contains(ppName)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); reiterate = true; } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); } // Now, invoke the postProcessBeanFactory callback of all processors handled so far. invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);//<5> invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory); } else { // Invoke factory processors registered with the context instance. invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory); } // Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let the bean factory post-processors apply to them! String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false); // Separate between BeanFactoryPostProcessors that implement PriorityOrdered, // Ordered, and the rest. List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>(); List<String> orderedPostProcessorNames = new ArrayList<>(); List<String> nonOrderedPostProcessorNames = new ArrayList<>(); for (String ppName : postProcessorNames) { if (processedBeans.contains(ppName)) { // skip - already processed in first phase above } else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class)); } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { orderedPostProcessorNames.add(ppName); } else { nonOrderedPostProcessorNames.add(ppName); } } // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered. sortPostProcessors(priorityOrderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); // Next, invoke the BeanFactoryPostProcessors that implement Ordered. List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size()); for (String postProcessorName : orderedPostProcessorNames) { orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } sortPostProcessors(orderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory); // Finally, invoke all other BeanFactoryPostProcessors. List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size()); for (String postProcessorName : nonOrderedPostProcessorNames) { nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory); // Clear cached merged bean definitions since the post-processors might have // modified the original metadata, e.g. replacing placeholders in values... beanFactory.clearMetadataCache(); } …… }