Spring-BeanPostProcessor的执行顺序

只需让BeanPostProcessor的实现类实现PriorityOrdered接口或者Ordered接口,并实现其getOrder()方法。

getOrder()方法的返回值越小将越先被执行。

PriorityOrdered和Ordered优先级为,实现PriorityOrdered接口的BeanPostProcessor执行优先级高于实现Ordered接口的BeanPostProcessor。之所以会这样,是因为registerBeanPostProcessors方法所决定的。因为底层存储BeanPostProcessor实现类实例的beanPostProcessors集合是线程安全地并且是有序的集合(CopyOnWriteArrayList),并且是先注册先执行。`

/** BeanPostProcessors to apply. */
	private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();

底层BeanPostProcessor注册机制实现

在该方法中通过ConfigurableListableBeanFactory的getBeanNamesForType方法,来获取IoC容器中所有实现了BeanPostProcessor接口的beanName,然后遍历这些beanName。

通过ConfigurableListableBeanFactory的isTypeMatch方法来判断指定的beanName是否实现了Priorit-yOrdered接口,如果实现了,则添加到priorityOrderedPostProcessors集合中。

通过isTypeMatch方法判断指定的beanName是否实现了Ordered接口,如果实现了,则添加到order-edPostProcessorNames集合中。

否则添加到nonOrderedPostProcessorNames集合中。

接下来就是对priorityOrdered集合以及orderedPostProcessorNames集合进行遍历,根据beanName来调用beanFactory的getBean方法获取Bean实例,最后注册到BeanFactory中。

// PostProcessorRegistrationDelegate#registerBeanPostProcessors(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, org.springframework.context.support.AbstractApplicationContext)
public static void registerBeanPostProcessors(
      ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

   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.
   int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
   beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

   // Separate between BeanPostProcessors that implement PriorityOrdered,
   // Ordered, and the rest.
   List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
   List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
   List<String> orderedPostProcessorNames = new ArrayList<>();
   List<String> nonOrderedPostProcessorNames = new ArrayList<>();
	// 首先注册的是实现了PriorityOrderd接口的BeanPostProcessor接口实现类
   for (String ppName : postProcessorNames) {
      if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
         BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
         priorityOrderedPostProcessors.add(pp);
         if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
         }
      } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
         orderedPostProcessorNames.add(ppName);
      } else {
         nonOrderedPostProcessorNames.add(ppName);
      }
   }

   // 对priorityOrderedPostProcessors集合进行排序
   sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
	 // 将priorityOrderedPostProcessors集合中的BeanPostProcessor实现类注册到IoC容器中
   registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

   // next,处理实现了Ordered接口的BeanPostProcessor接口实现类
   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);
      }
   }
	 // 对orderedPostProcessors集合进行排序
   sortPostProcessors(orderedPostProcessors, beanFactory);
	 // 将orderedPostProcessors集合中的BeanPostProcessor接口实现类注册到IoC容器中
   registerBeanPostProcessors(beanFactory, orderedPostProcessors);

   // 最后处理没有实现任何排序接口的BeanPostProcessor接口实现类
   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);
      }
   }
	 // 将nonOrderedPostProcessors集合中的BeanPostProcessor接口实现类注册到IoC容器中
   registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

   // Finally, re-register all internal BeanPostProcessors.
   sortPostProcessors(internalPostProcessors, beanFactory);
   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).
   beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

需注意的是BeanPostProcessor接口实现类实例化时机是早于普通Bean的实例化的,因此如果要实现该接口时需要特别注意依赖的资源是否已经准备就绪。

另外需要注意的一点是如果实现了MergedBeanDefinitionPostProcessor接口,也实现了PriorityOrde-red或Ordered接口,那么可能调用的优先级与期望的优先级不一样。这是因为在registerBeanPostP-rocessors方法的最后通过调用registerBeanPostProcessor方法来将internalPostProcessors集合中MergedBeanDefinitionPostProcessor接口实现类注册到IoC容器中。这会导致这部分实现类在IoC容器的注册顺序重排序。甚至会被重排到实现了Ordered(或者未实现Ordered)接口的BeanPostProcessor实现类之后。

接下来用代码验证下。

代码

首先定义一个类去实现MergedBeanDefinitionPostProcessor以及PriorityOrdered接口。

public class CustomizedMergedBeanPostProcessor implements MergedBeanDefinitionPostProcessor, PriorityOrdered {
    @Override
    public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {

    }

    @Override
    public int getOrder() {
        return 1;
    }
}

定义一个类只实现BeanPostProcessor接口。

public class CustomizedOrderedBeanPostProcessor implements BeanPostProcessor, Ordered {
    @Override
    public int getOrder() {
        return 2;
    }
}

编写测试类启动Spring应用上下文。

public class MainTest {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        context.register(
                CustomizedMergedBeanPostProcessor.class,
                CustomizedOrderedBeanPostProcessor.class);
        context.refresh();

    }
}

在PostProcessorRegistrationDelegate的第251行和255行分别打上断点。可以看到当程序执行到第251行时,beanFactory的属性beanPostProcessors集合中存储的BeanPostProccessor实现类的顺序符合我们的期望。

因为CustomizedMergedBeanPostProcessor实现了PriorityOrdered接口,所以它在CustomizedOrde-redBeanPostProcessor之前。
在这里插入图片描述
而当程序执行255行时,它们的顺序发生了变化,CustomizedOrderedBeanPostProcessor在Custom-izedMergedBeanPostProcessor之前。这也符合上面的解释。
在这里插入图片描述

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值