java注解的执行顺序_深入理解Spring的@Order注解和Ordered接口
前言
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接口相关推荐
- @requirespermissions注解是什么意思_如何基于spring开发自定义注解实现对接口访问频次限制?...
做JavaWeb的开发的同学们都应该遇到过,客户要求某个接口进行频次的限制,如每秒并发10个,或者短信验证码发送场景,60秒内只允许发送一次. 通常开发的小伙伴们肯定是拿到以上需求在接口逻辑里进行实现 ...
- java的for的执行顺序_对java for 循环执行顺序的详解
如下所示: for(表达式1;表达式2;表达式3) { //循环体 } 先执行"表达式1",再进行"表达式2"的判断,判断为真则执行 "循环体&quo ...
- Spring Aop 常见注解和执行顺序
欢迎关注方志朋的博客,回复"666"获面试宝典 来源:juejin.cn/post/7062506923194581029 Spring 一开始最强大的就是 IOC / AOP 两 ...
- java代码块执行顺序_Java笔记 | Java代码块执行顺序测试
最近笔试常常遇到考察Java代码块执行顺序的题目,网上查看博客错漏百出,特地自己测试了一下. 如有错漏,希望路过的大佬指出来,以便我进行更改. 先上代码吧! public class ClassA { ...
- java 构造函数的执行顺序
在此我用类似<Thinking in Java>的一个例子来说明 pakage com.yqs.test class Milk { publcic Milk() { System.out. ...
- vue 请求时方法执行顺序问题,异步请求无法同时处理多个接口,使用同步顺序执行:async/await使用
vue 请求时方法执行顺序问题,异步请求无法同时处理多个接口,使用同步顺序执行:async/await使用 异步解决方案:async/await 多个await,同步拿到数据再处理 多个接口处理拿到数 ...
- java 异步调用 事务_深入理解Spring注解@Async解决异步调用问题
序言:Spring中@Async 根据Spring的文档说明,默认采用的是单线程的模式的.所以在Java应用中,绝大多数情况下都是通过同步的方式来实现交互处理的. 那么当多个任务的执行势必会相互影响. ...
- java 判断顺序_通过指令码来判断Java代码的执行顺序(++问题与return和finally的问题)...
问题 在<深入理解Java虚拟机>一书中遇到了如下代码: public int method() { int i; try { i = 1; return i; } catch (Exce ...
- java 控制线程的顺序_【Java多线程系列四】控制线程执行顺序
packagecom.concurrent.test;importjava.util.concurrent.CountDownLatch;importorg.junit.Assert;importor ...
最新文章
- Mnist数据集简介
- penalized_tanh可视化
- java获取文件夹下所有文件的名称
- C# 3.0 扩展方法
- 30个免费资源:涵盖机器学习、深度学习、NLP及自动驾驶
- 【Python】Paramiko模块在Windows10中import ssl报错的处理方法
- MAC 修改文件夹以及子文件夹和子文件权限 以及 修改文件夹owner
- go get 的不再src目录中_如何正确的开始用Go编程
- 在Ubuntu18.04上安装Nvidia驱动
- quartus仿真10:74283的基本功能
- python时间序列模型有哪些_时间序列模型(ARIMA)
- 23种设计模式(三)组件协作之策略模式
- 影像测量仪使用的注意点
- MySQL5.5安装包 安装详解
- PN结是什么?PN结有什么特征?PN结的应用
- 大华网络摄像头ip搜索工具_【技术篇】NVR4.0接第三方摄像头,安排!
- 迅雷mac版精简安装教程
- 如何在虚拟机VMware安装配置功能强大爱快软路由
- 三星手机和计算机如何连接打印机,WIFI当道 手把手教你如何实现无线打印
- Linux高性能并发服务器发开学习(二进程和线程)