1。问题描述最近在整理项目中的基础模块,希望能把自动扫描(@ComponentScan)方式改为@Configuration-based方式,这样在写测试类的时候,可以有选择性的组装相关的bean基础设施。通过这样的整理和思考,可以提高模块的内聚性。但是在运行的过程中,根据实际情况,认为有些bean的实例化是有顺序的,所以理所当然的认为bean实例化的顺序可以通过@Order注解(或者Ordered界面)。其实并不是。2.问题分析我们定义了以下三个bean。实现Ordered接口,分别返回3、2、1。根据预期的效果,值越小,初始化越早。@Slf4j@ComponentpublicclassAOrderBeanimplementsOrdered{publicAOrderBean(){log.info("initAOrderBean");}@OverridepublicintgetOrder(){返回3;}}@Slf4j@ComponentpublicclassBOrderBeanimplementsOrdered{publicBOrderBean(){log.info("initBOrderBean");}@OverridepublicintgetOrder(){返回2;}}@Slf4j@ComponentpublicclassCOrderBeanimplementsOrdered{publicCOrderBean(){log.info("initCOrderBean");}@OverridepublicintgetOrder(){返回1;}}程序运行结果:从运行结果分析,Ordered接口没有达到预期的效果。3、Order排序的原理通过分析Spring源码发现,基于Order的排序问题是通过AnnotationAwareOrderComparator实现的。调用比较器的地方就是Order生效的地方。4.全局搜索订单生效场景。在Spring和SpringBoot项目中,这个类用在了以下几个地方:4.1spring-context模块如上图所示。在spring-context模块中,以下接口对Order生效:Condition接口DeferredImportSelector导入外部程序集配置ApplicationListenerEventListenerFactorySchedulingConfigurer4.2spring-core模块如上图,当SpringFactoriesLoader根据指定类型加载相应配置时,即可生效.全局搜索该方法如下:SpringBoot在启动时读取spring.factories中的相关配置时使用该方法。4.3spring-test模块如上图所示:ApplicationContextInitializerTestExecutionListener4.4spring-web模块4.5spring-bootspring-boot中可以被影响的有:ApplicationRunnerCommandLineRunnerErrorViewResolvergetSpringFactoriesInstances方法调用的地方ApplicationListenerFailureAnalyzerTypeSupplierErrorPageRegistrarWebServerFactoryCustomizerServletContextInitializer5.其他已知生效场景5.1@Aspect注解通过@Aspect对Whenthesamecallpointisenhanced,whentherearemultipleenhancementsandyouwanttocontroltheirorder,youcanuse@Order5.2assemblycollectiontype@ComponentpublicclassFilterChain{privateList
