只需让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 {@Overridepublic void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {}@Overridepublic int getOrder() {return 1;}
}

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

public class CustomizedOrderedBeanPostProcessor implements BeanPostProcessor, Ordered {@Overridepublic 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之前。这也符合上面的解释。

Spring-BeanPostProcessor的执行顺序相关推荐

  1. 顺序执行_执行流程 | 你真的了解Spring AOP的执行顺序吗?

    Hi! 我是小小,我们又见面了,今天的主要内容是,你真的了解Spring AOP的执行顺序吗?跟随着我的脚步,一块丈量世界,了解世界,重新认识,重新了解Spring AOP的执行顺序. 聊一聊毕业四个 ...

  2. gtw-050090|执行拦截器时发生异常_执行流程 | 你真的了解Spring AOP的执行顺序吗?...

    Hi! 我是小小,我们又见面了,今天的主要内容是,你真的了解Spring AOP的执行顺序吗?跟随着我的脚步,一块丈量世界,了解世界,重新认识,重新了解Spring AOP的执行顺序. 聊一聊毕业四个 ...

  3. 执行流程 | 你真的了解Spring AOP的执行顺序吗?

    Hi! 我是小小,我们又见面了,今天的主要内容是,你真的了解Spring AOP的执行顺序吗?跟随着我的脚步,一块丈量世界,了解世界,重新认识,重新了解Spring AOP的执行顺序. 聊一聊毕业四个 ...

  4. 你真的确定Spring AOP的执行顺序吗

    本文内容重点: 问题描述 Spring AOP执行顺序 探究顺序错误的真相 代码验证 结论   问题描述 公司新项目需要搭建一个新的前后分离HTTP服务,我选择了目前比较熟悉的SpringBoot W ...

  5. spring 基于XML的申明式AspectJ通知的执行顺序

    spring 基于XML的申明式AspectJ通知的执行顺序 关于各种通知的执行顺序,结论:与配置文件中的申明顺序有关 1. XML文件配置说明 图片来源:<Java EE企业级应用开发教程&g ...

  6. java注解的执行顺序_深入理解Spring的@Order注解和Ordered接口

    前言 Spring的@Order注解或者Ordered接口大家都知道是控制顺序的,那么它们到底是控制什么顺序的?是控制Bean的注入顺序,还是Bean的实例化顺序,还是Bean的执行顺序呢?那么我们先 ...

  7. Spring Aop 常见注解和执行顺序

    欢迎关注方志朋的博客,回复"666"获面试宝典 来源:juejin.cn/post/7062506923194581029 Spring 一开始最强大的就是 IOC / AOP 两 ...

  8. Spring Boot相关知识(二) Spring Boot项目启动的执行顺序和原理

    2019独角兽企业重金招聘Python工程师标准>>> 1. 环境,程序入口 @SpringBootApplication public class Application {pub ...

  9. spring 中构造Constructor、@Autowired、@PostConstruct、静态方法的执行顺序 (@PostConstruct 说明)

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到教程. 1. 关于注解 PostConstruct  public @interface PostConst ...

  10. Spring面试之不同版本AOP执行顺序详解

    1.AOP常用注解: @Before 前置通知:目标方法之前执行 @After 后置通知:目标方法之后执行(始终执行) @AfterReturning 返回后通知:执行方法结束前执行(异常不执行) @ ...

最新文章

  1. JAVA调用R语言之Rserve
  2. 【设计模式系列】OO设计原则之LSP-Liskov替换原则
  3. 与虫子尾交3d动画网站_PPT中最酷的效果 —— 3D模型全解
  4. Python3引号创建字符串
  5. 设c语言中 一个int型数据库,最新真实全国二级C选择题真题第1套
  6. 云服务 华为p10 短信_苹果、小米、华为,手机云服务哪家强?
  7. 洛谷P1102 A-B
  8. Java全套学习资料
  9. HDS存储管理工具命令行汇总
  10. 开放原子训练营(第一季)铜锁探密:基于铜锁,在前端对登录密码进行加密,实现隐私数据保密性
  11. 对高校深入开展翻转课堂的建议
  12. python 离线安装驱动
  13. 软件测试220道试题及答案
  14. 表格中insertBefore方法的使用(The node before which the new node is to be inserted is not a child of this no)
  15. 端口映射工具:ngrok的使用
  16. EMC电磁兼容3:仪器受电磁辐射干扰怎么办?
  17. java创始人现在在哪里直播,三年败光120亿,他曾是某电商巨头创始人,如今却靠直播度日!...
  18. python数据分析(三)
  19. APIPOST 常见设置项
  20. 【王喆-推荐系统】(task3)深度学习基础和TensorFlow入门(基础架构篇)

热门文章

  1. 非线性优化:Ax=b求解的几种算法
  2. 优必选悟空智能机器人怎么读绘本_优必选发布悟空机器人及操作系统ROSA,关于估值这么回应…...
  3. 信贷违约风险预测(四)TrAiNiNG MoDeL
  4. 算法:剑指 Offer 06. 从尾到头打印链表
  5. DSSM,Deep Structured Semantic Models
  6. pil对图像加透明 python_分享一个骚操作,用 Python 来 P 图
  7. 本地Git仓库关联Github项目
  8. 斯坦福大学自然语言处理第五课“拼写纠错(Spelling Correction)”
  9. 三次握手四次挥手必掌握,看了绝对不吃亏!
  10. 58java面试题_58到家,java开发实际面试题