前言

Spring的@Order注解或者Ordered接口大家都知道是控制顺序的,那么它们到底是控制什么顺序的?是控制Bean的注入顺序,还是Bean的实例化顺序,还是Bean的执行顺序呢?那么我们先直接给出结论再来验证结论。

结论:Spring的@Order注解或者Ordered接口,不决定Bean的加载顺序和实例化顺序,只决定Bean的执行顺序。

实例论证:@Order不决定Bean的加载和实例化顺序

步骤一:创建DemoService接口和三个实现类,分别打上注解@Order(0)-DemoServiceImpl01、@Order(1)-DemoServiceImpl02、@Order(2)-DemoServiceImpl03,观察实例化顺序。

@Service

@Order(0)

public class DemoServiceImpl01 implements DemoService {

public DemoServiceImpl01() {

System.out.println("DemoServiceImpl01被实例化了");

}

}

@Service

@Order(1)

public class DemoServiceImpl02 implements DemoService {

public DemoServiceImpl02() {

System.out.println("DemoServiceImpl02被实例化了");

}

}

@Service

@Order(2)

public class DemoServiceImpl03 implements DemoService {

public DemoServiceImpl03() {

System.out.println("DemoServiceImpl03被实例化了");

}

}

// 运行结果如下

DemoServiceImpl01被实例化了

DemoServiceImpl02被实例化了

DemoServiceImpl03被实例化了

步骤二:改变DemoService接口三个实现类的注解序值,@Order(2)-DemoServiceImpl01、@Order(1)-DemoServiceImpl02、@Order(0)-DemoServiceImpl03,观察实例化顺序

@Service

@Order(2)

public class DemoServiceImpl01 implements DemoService {

public DemoServiceImpl01() {

System.out.println("DemoServiceImpl01被实例化了");

}

}

@Service

@Order(1)

public class DemoServiceImpl02 implements DemoService {

public DemoServiceImpl02() {

System.out.println("DemoServiceImpl02被实例化了");

}

}

@Service

@Order(0)

public class DemoServiceImpl03 implements DemoService {

public DemoServiceImpl03() {

System.out.println("DemoServiceImpl03被实例化了");

}

}

// 运行结果如下

DemoServiceImpl01被实例化了

DemoServiceImpl02被实例化了

DemoServiceImpl03被实例化了

结果:当改变DemoService接口的三个实现类注解序值时,类的加载和实例化顺序根本没有变化,即@Order注解不决定Bean的加载和实例化顺序。

实例论证:@Order决定Bean的执行顺序

步骤一:创建RunServiceImpl类,并通过构造函数依赖注入DemoService的三个实现类,且循序依次执行三个实现类方法,观察Bean的执行顺序。

@Service

public class RunServiceImpl implements RunService {

public RunServiceImpl(List demoServices) {

demoServices.forEach(demoService -> demoService.say());

}

}

@Service

@Order(0)

public class DemoServiceImpl01 implements DemoService {

public DemoServiceImpl01() {

System.out.println("DemoServiceImpl01被实例化了");

}

@Override

public void say() {

System.out.println("DemoServiceImpl01被执行了");

}

}

@Service

@Order(1)

public class DemoServiceImpl02 implements DemoService {

public DemoServiceImpl02() {

System.out.println("DemoServiceImpl02被实例化了");

}

@Override

public void say() {

System.out.println("DemoServiceImpl02被执行了");

}

}

@Service

@Order(2)

public class DemoServiceImpl03 implements DemoService {

public DemoServiceImpl03() {

System.out.println("DemoServiceImpl03被实例化了");

}

@Override

public void say() {

System.out.println("DemoServiceImpl03被执行了");

}

}

// 运行结果如下

DemoServiceImpl01被执行了

DemoServiceImpl02被执行了

DemoServiceImpl03被执行了

步骤二:改变DemoService接口三个实现类的注解序值,@Order(2)-DemoServiceImpl01、@Order(1)-DemoServiceImpl02、@Order(0)-DemoServiceImpl03,观察Bean的执行顺序。

@Service

public class RunServiceImpl implements RunService {

public RunServiceImpl(List demoServices) {

demoServices.forEach(demoService -> demoService.say());

}

}

@Service

@Order(2)

public class DemoServiceImpl01 implements DemoService {

public DemoServiceImpl01() {

System.out.println("DemoServiceImpl01被实例化了");

}

@Override

public void say() {

System.out.println("DemoServiceImpl01被执行了");

}

}

@Service

@Order(1)

public class DemoServiceImpl02 implements DemoService {

public DemoServiceImpl02() {

System.out.println("DemoServiceImpl02被实例化了");

}

@Override

public void say() {

System.out.println("DemoServiceImpl02被执行了");

}

}

@Service

@Order(0)

public class DemoServiceImpl03 implements DemoService {

public DemoServiceImpl03() {

System.out.println("DemoServiceImpl03被实例化了");

}

@Override

public void say() {

System.out.println("DemoServiceImpl03被执行了");

}

}

// 运行结果如下

DemoServiceImpl03被执行了

DemoServiceImpl02被执行了

DemoServiceImpl01被执行了

结果:当改变DemoService接口的三个实现类注解序值时,类的执行顺序也随之发生变化,即@Order决定Bean的执行顺序。

@Order注解或Ordered接口决定Bean的执行顺序原理分析

通过上面实例论证,大家应该清楚@Order注解或Ordered接口只是决定了Bean的执行顺序,那么Spring是如何在依赖注入时完成根据@Order注解或Ordered接口控制Bean执行顺序?

原理分析:

当通过构造函数或者方法参数注入进某个List时,Spring的DefaultListableBeanFactory类会在注入时调用AnnotationAwareOrderComparator.sort(listA)帮我们去完成根据@Order或者Ordered接口序值排序。

备注:

AnnotationAwareOrderComparator是OrderComparator的子类,而OrderComparator实现比较器Comparator接口,AnnotationAwareOrderComparator.sort(listA)会调用父类sort方法,会根据@Order或者Ordered接口设置的int序值重写sort方法进行排序,值越小优先级越高。

我的专栏

本文地址:https://blog.csdn.net/zkc7441976/article/details/112548075

希望与广大网友互动??

点此进行留言吧!

java注解的执行顺序_深入理解Spring的@Order注解和Ordered接口相关推荐

  1. @requirespermissions注解是什么意思_如何基于spring开发自定义注解实现对接口访问频次限制?...

    做JavaWeb的开发的同学们都应该遇到过,客户要求某个接口进行频次的限制,如每秒并发10个,或者短信验证码发送场景,60秒内只允许发送一次. 通常开发的小伙伴们肯定是拿到以上需求在接口逻辑里进行实现 ...

  2. java的for的执行顺序_对java for 循环执行顺序的详解

    如下所示: for(表达式1;表达式2;表达式3) { //循环体 } 先执行"表达式1",再进行"表达式2"的判断,判断为真则执行 "循环体&quo ...

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

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

  4. java代码块执行顺序_Java笔记 | Java代码块执行顺序测试

    最近笔试常常遇到考察Java代码块执行顺序的题目,网上查看博客错漏百出,特地自己测试了一下. 如有错漏,希望路过的大佬指出来,以便我进行更改. 先上代码吧! public class ClassA { ...

  5. java 构造函数的执行顺序

    在此我用类似<Thinking in Java>的一个例子来说明 pakage com.yqs.test class Milk { publcic Milk() { System.out. ...

  6. vue 请求时方法执行顺序问题,异步请求无法同时处理多个接口,使用同步顺序执行:async/await使用

    vue 请求时方法执行顺序问题,异步请求无法同时处理多个接口,使用同步顺序执行:async/await使用 异步解决方案:async/await 多个await,同步拿到数据再处理 多个接口处理拿到数 ...

  7. java 异步调用 事务_深入理解Spring注解@Async解决异步调用问题

    序言:Spring中@Async 根据Spring的文档说明,默认采用的是单线程的模式的.所以在Java应用中,绝大多数情况下都是通过同步的方式来实现交互处理的. 那么当多个任务的执行势必会相互影响. ...

  8. java 判断顺序_通过指令码来判断Java代码的执行顺序(++问题与return和finally的问题)...

    问题 在<深入理解Java虚拟机>一书中遇到了如下代码: public int method() { int i; try { i = 1; return i; } catch (Exce ...

  9. java 控制线程的顺序_【Java多线程系列四】控制线程执行顺序

    packagecom.concurrent.test;importjava.util.concurrent.CountDownLatch;importorg.junit.Assert;importor ...

最新文章

  1. Mnist数据集简介
  2. penalized_tanh可视化
  3. java获取文件夹下所有文件的名称
  4. C# 3.0 扩展方法
  5. 30个免费资源:涵盖机器学习、深度学习、NLP及自动驾驶
  6. 【Python】Paramiko模块在Windows10中import ssl报错的处理方法
  7. MAC 修改文件夹以及子文件夹和子文件权限 以及 修改文件夹owner
  8. go get 的不再src目录中_如何正确的开始用Go编程
  9. 在Ubuntu18.04上安装Nvidia驱动
  10. quartus仿真10:74283的基本功能
  11. python时间序列模型有哪些_时间序列模型(ARIMA)
  12. 23种设计模式(三)组件协作之策略模式
  13. 影像测量仪使用的注意点
  14. MySQL5.5安装包 安装详解
  15. PN结是什么?PN结有什么特征?PN结的应用
  16. 大华网络摄像头ip搜索工具_【技术篇】NVR4.0接第三方摄像头,安排!
  17. 迅雷mac版精简安装教程
  18. 如何在虚拟机VMware安装配置功能强大爱快软路由
  19. 三星手机和计算机如何连接打印机,WIFI当道 手把手教你如何实现无线打印
  20. Linux高性能并发服务器发开学习(二进程和线程)

热门文章

  1. 微信小程序日期相减得出天数
  2. vs 添加ico图 到资源
  3. Apache Tomcat 7.0.93 发布,开源 Java Web 应用服务器
  4. Redis (二)_ jedis的使用
  5. 配置国内 Docker Registry Mirror
  6. mapreduce作业reduce被大量kill掉
  7. UVa11300 - Spreading the Wealth
  8. Kotlin语法(基础)
  9. 今天看到两个题 写出来思考一下
  10. 描述C#多线程中 lock关键字