前言
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<DemoService> 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<DemoService> 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方法进行排序,值越小优先级越高。
我的专栏
- 设计模式
- 认证授权框架实战
- java进阶知识
- maven进阶知
- spring进阶知识
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)