spring之BeanFactoryPostProcessor执行流程

转载自:https://www.jianshu.com/p/5323114c0d05

描述

BeanFactoryPostProcessor 为spring在容器初始化时对外对外暴露的扩展点,Spring IoC容器允许BeanFactoryPostProcessor在容器加载注册BeanDefinition完成之后读取BeanDefinition(配置元数据),并可以修改它。

下面跟踪spring源码阅读BeanFactoryPostProcessor的加载机制以及执行时机

执行入口

// AbstractApplicationContext 类
 @Override
    public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { //容器刷新前的处理方法 prepareRefresh(); ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); //使用容器前beanFactory的前置处理方法 prepareBeanFactory(beanFactory); try { postProcessBeanFactory(beanFactory); //在容器中执行bean工厂后置处理器 invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. registerBeanPostProcessors(beanFactory); initMessageSource(); initApplicationEventMulticaster(); onRefresh(); registerListeners(); finishBeanFactoryInitialization(beanFactory); finishRefresh(); } catch (BeansException ex) { // Destroy already created singletons to avoid dangling resources. destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { resetCommonCaches(); } } } 

spring IOC容器ApplicationContext 在完成包扫描,xml配置加载(BeanDefinition注册后)都会调用refresh方法完成容器的刷新工作即容器的启动工作。

在refresh方法中有如下一行:

//执行容器工厂的后置处理器,
invokeBeanFactoryPostProcessors(beanFactory); 

此行就是spring执行容器后置处理器的入口方法,下面接着跟踪invokeBeanFactoryPostProcessors方法:

    /**
     * 实例化并调用所有已注册的BeanFactoryPostProcessor bean,如果给定,则遵守显式顺序。
     */
    protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { //通过PostProcessorRegistrationDelegate的invokeBeanFactoryPostProcessors方法执行BeanFactoryPostProcessor PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); } 

invokeBeanFactoryPostProcessors 方法很简单,通过PostProcessorRegistrationDelegate类的静态方法invokeBeanFactoryPostProcessors执行后置处理器。此方法完成两件事:

  1. 调用getBeanFactoryPostProcessors()方法获取手工注册到ApplicationContext的容器后置处理器集合
  2. 调用静态方法invokeBeanFactoryPostProcessors并传入后置处理器集合批量执行后置处理器

后置处理器执行

在上面看到了spring是通过静态方法invokeBeanFactoryPostProcessors执行后置处理,下面跟踪invokeBeanFactoryPostProcessors方法:

// 类PostProcessorRegistrationDelegate
public static void invokeBeanFactoryPostProcessors( ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { //保存所有后置处理器bean名称的集合 Set<String> processedBeans = new HashSet<>(); //判断beanFactory 是否是BeanDefinitionRegistry // 当是BeanDefinitionRegistry 时 // 将beanFactoryPostProcessors 分为BeanFactoryPostProcessor集合与BeanDefinitionRegistryPostProcessor集合 if (beanFactory instanceof BeanDefinitionRegistry) { BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; //BeanFactoryPostProcessor集合 List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>(); //BeanDefinitionRegistryPostProcessor集合 List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>(); for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { //遍历查询BeanFactoryPostProcessor是否为BeanDefinitionRegistryPostProcessor if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { //当前postProcessor为BeanDefinitionRegistryPostProcessor是执行postProcessBeanDefinitionRegistry方法 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<>(); // 首先在容器中查找实现了PriorityOrdered接口的的BeanDefinitionRegistryPostProcessors(bean定义注册后置处理器)名称 // 将查找到的名称集合放置到processedBeans中,以及将后置处理器添加到集合currentRegistryProcessors中 // 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)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } //对currentRegistryProcessors集合排序 sortPostProcessors(currentRegistryProcessors, beanFactory); //将当前查找到的currentRegistryProcessors放置到注册后置处理器集合中 registryProcessors.addAll(currentRegistryProcessors); //遍历循环执行currentRegistryProcessors集合中的bean定义注册后置处理器 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); //清空currentRegistryProcessors集合 currentRegistryProcessors.clear(); // 下来在容器中查找实现了Ordered接口的的BeanDefinitionRegistryPostProcessors(bean定义注册后置处理器)名称 // 将查找到的名称集合放置到processedBeans中,以及将后置处理器添加到集合currentRegistryProcessors中 // 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)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } //对currentRegistryProcessors集合排序 sortPostProcessors(currentRegistryProcessors, beanFactory); //将当前查找到的currentRegistryProcessors放置到注册后置处理器集合registryProcessors中 registryProcessors.addAll(currentRegistryProcessors); //遍历循环执行currentRegistryProcessors集合中的bean定义注册后置处理器 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); //清空currentRegistryProcessors集合 currentRegistryProcessors.clear(); // 最后在容器中查找其余BeanDefinitionRegistryPostProcessors(bean定义注册后置处理器)名称 // 将查找到的名称集合放置到processedBeans中,以及将后置处理器添加到集合currentRegistryProcessors中 // 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); } 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<>(); 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<>(); for (String postProcessorName : nonOrderedPostProcessorNames) { nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory); beanFactory.clearMetadataCache(); } 

此方法比较长,根据传入beanFactory类型可分为两部分:

  1. beanFactory是BeanDefinitionRegistry类型时

此条件下完成如下流程:

  1. 遍历传入后置处理器集合查找类型为BeanDefinitionRegistryPostProcessor的后置处理器,调用后置处理器的postProcessBeanDefinitionRegistry方法
  2. 在容器中查找所有的实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor集合,对后置处理器集合排序,遍历,执行后置处理的postProcessBeanDefinitionRegistry方法如下:
    private static void invokeBeanDefinitionRegistryPostProcessors( Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) { for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) { postProcessor.postProcessBeanDefinitionRegistry(registry); } } 
  1. 在容器中查找所有实现了Ordered接口的BeanDefinitionRegistryPostProcessor集合,对后置处理器集合排序,遍历,执行后置处理的postProcessBeanDefinitionRegistry方法。
  2. 在容器中查找其它(未实现排序接口)的BeanDefinitionRegistryPostProcessor并添加到集合nonOrderedPostProcessors中,对后置处理器集合排序,遍历,执行后置处理的postProcessBeanDefinitionRegistry方法
  1. 当前所有的BeanDefinitionRegistryPostProcessor处理器的方法postProcessBeanDefinitionRegistry 执行完毕后,执行其父类postProcessBeanFactory方法
  1. 执行所有非BeanDefinitionRegistryPostProcessor类型的后置处理器的postProcessBeanFactory方法
  1. beanFactory非BeanDefinitionRegistry类型时

此条件下完成如下流程:

  1. 遍历传入后置处理器集合,执行后置处理器的postProcessBeanFactory方法,如下:
    private static void invokeBeanFactoryPostProcessors( Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) { //遍历BeanFactoryPostProcessor集合执行postProcessBeanFactory方法 for (BeanFactoryPostProcessor postProcessor : postProcessors) { postProcessor.postProcessBeanFactory(beanFactory); } } 
  1. 在容器中(beanFactory.getBeanNamesForType)查找所有的实现了PriorityOrdered接口的BeanFactoryPostProcessor集合,对后置处理器集合排序,遍历,执行后置处理。
  2. 在容器中查找所有实现了Ordered接口的BeanFactoryPostProcessor集合,对后置处理器集合排序,遍历,执行后置处理。
  3. 在容器中查找其它(未实现排序接口)的BeanFactoryPostProcessor并添加到集合nonOrderedPostProcessors中,对后置处理器集合排序,遍历,执行后置处

BeanFactoryPostProcessor类型

在上面看到spring主要将BeanFactoryPostProcessor划分了两类:

扫描二维码关注公众号,回复: 8469249 查看本文章
  • 正常的BeanFactoryPostProcessor
  • BeanDefinitionRegistry类型的BeanDefinitionRegistryPostProcessor

在执行流程中可以看到spring先执行了BeanDefinitionRegistryPostProcessor类型的postProcessBeanDefinitionRegistry方法,再执行BeanDefinitionRegistryPostProcessor和正常BeanFactoryPostProcessor的postProcessBeanFactory方法。

spring对BeanDefinitionRegistryPostProcessor的解释是:允许在正常的BeanFactoryPostProcessor执行检测开始之前注册更多的自定义bean。也就是说BeanDefinitionRegistryPostProcessor的方法postProcessBeanDefinitionRegistry可以在后置处理器执行前自定义注册更多的BeanDefinition。

例如:spring实现的ConfigurationClassPostProcessor用于注册注解@Configuration标识的类里面定义的BeanDefinition


BeanFactoryPostProcessor 执行的整体流程:

  1. ApplicationContext的refresh方法
  2. ApplicationContext的invokeBeanFactoryPostProcessors方法
  3. PostProcessorRegistrationDelegate的invokeBeanFactoryPostProcessors

refresh()-> invokeBeanFactoryPostProcessors()->PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors()

BeanFactoryPostProcessor执行的优先级:

  1. 首先是实现了PriorityOrdered接口的,排序执行
  2. 下来是实现了Ordered接口的,排序执行
  3. 最后是其它(未实现排序接口),顺序执行

BeanFactoryPostProcessor获取机制:

  1. 首先获取手动注册ApplicationContext的集合
  2. 再次是通过beanFactory.getBeanNamesForType查找所有已注册的BeanFactoryPostProcessor的bean定义并实例化。






猜你喜欢

转载自www.cnblogs.com/UUUz/p/12170437.html