Spring中的BeanPostProcessor的注册

在应用上下文的主refresh方法中,专门有一个步骤是用来注册BeanPostProcessor类型的bean,大体过程就是从bean工厂获取该类型的bean然后设置到专门的属性中。本文就来看一下这个注册过程是怎样的。


java
spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}

BeanFactoryPostProcessor的执行一样,还是委托给PostProcessorRegistrationDelegate类来处理。

java
spring-context/src/main/java/org/springframework/context/support/PostProcessorRegistrationDelegate.java
public static void registerBeanPostProcessors(
        ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

    // WARNING: Although it may appear that the body of this method can be easily
    // refactored to avoid the use of multiple loops and multiple lists, the use
    // of multiple lists and multiple passes over the names of processors is
    // intentional. We must ensure that we honor the contracts for PriorityOrdered
    // and Ordered processors. Specifically, we must NOT cause processors to be
    // instantiated (via getBean() invocations) or registered in the ApplicationContext
    // in the wrong order.
    //
    // Before submitting a pull request (PR) to change this method, please review the
    // list of all declined PRs involving changes to PostProcessorRegistrationDelegate
    // to ensure that your proposal does not result in a breaking change:
    // https://github.com/spring-projects/spring-framework/issues?q=PostProcessorRegistrationDelegate+is%3Aclosed+label%3A%22status%3A+declined%22

    // 获取BeanPostProcessor类型的bean的名称
    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

    // Register BeanPostProcessorChecker that logs an info message when
    // a bean is created during BeanPostProcessor instantiation, i.e. when
    // a bean is not eligible for getting processed by all BeanPostProcessors.
    /*
     *
     * getBeanPostProcessorCount()表示那些在容器中,不能get的bean后置处理器个数,这些对象被保存在beanFactory的独立属性中
     * 注意,这里的+1表示下一句add的BeanPostProcessorChecker
     * postProcessorNames表示那些确实被保存在容器中的map里面的后置处理器个数
     *
     */
    int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
    beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

    // Separate between BeanPostProcessors that implement PriorityOrdered,
    // Ordered, and the rest.
    /*
     * 和上面那个方法处理BeanFactoryPostProcessor一样,这里对BeanPostProcessor进行分类
     * 先按照PriorityOrdered的实现类进行分类
     * 再按照Ordered的实现类进行分类
     * 最后剩下的归为一类
     *
     */
    List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
    List<String> orderedPostProcessorNames = new ArrayList<>();
    List<String> nonOrderedPostProcessorNames = new ArrayList<>();
    for (String ppName : postProcessorNames) {
        // 实现了PriorityOrdered接口的情况
        if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            /*
             * 注意,如果postProcessor没被创建,那么在这里会被创建,
             * 如AutowiredAnnotationBeanPostProcessor,在AnnotationConfigUtils.registerAnnotationConfigProcessors中注册的是BeanDefinition,
             * 而不是直接注入对象实例,Spring这样做,可能是让这些beanPostProcessor也经历完整的生命周期,可以对其进行控制
             */
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            priorityOrderedPostProcessors.add(pp);
            // 筛选出处理特定bean定义类型的后置处理器
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
        // 实现了Ordered接口的情况
        else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
            orderedPostProcessorNames.add(ppName);
        }
        // 没有实现上面两种排序接口的情况
        else {
            nonOrderedPostProcessorNames.add(ppName);
        }
    }

    // First, register the BeanPostProcessors that implement PriorityOrdered.
    // 排序
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    // 这里的register其实内部也是执行的addBeanPostProcessor
    registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

    // Next, register the BeanPostProcessors that implement Ordered.
    List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
    for (String ppName : orderedPostProcessorNames) {
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        orderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    // 排序
    sortPostProcessors(orderedPostProcessors, beanFactory);
    // 注册
    registerBeanPostProcessors(beanFactory, orderedPostProcessors);

    // Now, register all regular BeanPostProcessors.
    List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
    for (String ppName : nonOrderedPostProcessorNames) {
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        nonOrderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

    // Finally, re-register all internal BeanPostProcessors.
    sortPostProcessors(internalPostProcessors, beanFactory);
    // 重新注册所有MergedBeanDefinitionPostProcessor类型的bean
    registerBeanPostProcessors(beanFactory, internalPostProcessors);

    // Re-register post-processor for detecting inner beans as ApplicationListeners,
    // moving it to the end of the processor chain (for picking up proxies etc).
    /*
     * 再次注入了一个BeanPostProcessor, 其作用是检查ApplicationListener
     * 注意,addBeanPostProcessor会先remove,再add,所以不会存在重复的情况
     * 这里之所以要add的目的不是为了添加,而是把这个后置处理器放在最后执行
     *
     */
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

该方法按照下面的类别筛选出后置处理器,并按照顺序依次注册到bean工厂中。

  • 实现了PriorityOrdered接口;
  • 实现了Ordered接口;
  • 两个接口都没有实现;

真正的注册操作是在同名的私有方法中进行的。

java
spring-context/src/main/java/org/springframework/context/support/PostProcessorRegistrationDelegate.java
private static void registerBeanPostProcessors(
        ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {

    if (beanFactory instanceof AbstractBeanFactory) {
        // Bulk addition is more efficient against our CopyOnWriteArrayList there
        // 一次添加多个processor
        ((AbstractBeanFactory) beanFactory).addBeanPostProcessors(postProcessors);
    }
    else {
        for (BeanPostProcessor postProcessor : postProcessors) {
            // 一次添加一个processor
            beanFactory.addBeanPostProcessor(postProcessor);
        }
    }
}

接下来看一下bean工厂的addBeanPostProcessor方法。

java
spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java
@Override
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
    Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
    // Remove from old position, if any
    this.beanPostProcessors.remove(beanPostProcessor);
    // Add to end of list
    this.beanPostProcessors.add(beanPostProcessor);
}
public void addBeanPostProcessors(Collection<? extends BeanPostProcessor> beanPostProcessors) {
    this.beanPostProcessors.removeAll(beanPostProcessors);
    this.beanPostProcessors.addAll(beanPostProcessors);
}

可以看到,这里先从列表移除了所要注册的后置处理器,然后再添加。

在上面publicregisterBeanPostProcessors方法中对MergedBeanDefinitionPostProcessor类型的bean的进行了特殊处理,也就是在注册了所有的后置处理器后,再次注册一下这个类型的后置处理器,这样会让该类型的后置处理器在整个列表的末尾而且是连续的,因为会先移除再添加。