前言我们知道Spring的@Order注释和Ordered接口控制着顺序,那么控制着什么样的顺序呢? 是否要控制Bean的注入顺序、Bean的实例化顺序或Bean的执行顺序? 那么,直接得出结论后再验证结论吧。
结论:Spring的@Order注解或者Ordered接口,不决定Bean的加载顺序和实例化顺序,只决定Bean的执行顺序。
论证: @Order创建不确定Bean加载和实例化顺序的步骤DemoService接口和三个实现类,分别为@order(0)-DemoServiceImpl01、@order(1)
@service@order(0) publicclassdemoserviceimpl 01 implementsdemoserviceimpl 01 ) system.out.printtem } @service@order(1) publicclassdemoserviceimpl 02 implementsdemoserviceimpl 02 ) system.out.ppi } @service@order(2) publicclassdemoserviceimpl 03 implementsdemoserviceimpl 03 ) ) system.out.pppl }//实例化DemoServiceImpl01、实例化DemoServiceImpl02、实例化DemoServiceImpl03的步骤DemoService接口的三个实现类的注释序列值
@service@order(2) publicclassdemoserviceimpl 01 implementsdemoserviceimpl 01 ) system.out.printtem } @service@order(1) publicclassdemoserviceimpl 02 implementsdemoserviceimpl 02 ) system.out.ppi } @service@order(0) publicclassdemoserviceimpl 03 implementsdemoserviceimpl 03 ) ) system.out.pppl }//实例化了DemoServiceImpl01实例化了DemoServiceImpl02实例化了DemoServiceImpl03的结果是更改了DemoService接口的三个实现类注释顺序值
实践论: @Order创建确定Bean执行顺序的步骤RunServiceImpl类,依赖于通过构造函数注入DemoService的3个实现类,依次执行3个实现类方法,观察Bean的执行顺序
@ servicepublicclassrunserviceimplimplementsrunserviceimpl (listdemoservicedemoservices ) demoservices. } @service@order(0) publicclassdemoserviceimpl 01 implementsdemoserviceimpl 01 ) ) system.out.pppl } }@service@order(1)公共类d
emoServiceImpl02 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的执行顺序。
@Servicepublic 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方法进行排序,值越小优先级越高。