1.为什么需要控制加载顺序?Springboot遵循约定优于配置的原则,极大的解决了配置繁琐的问题。在此基础上提供了spi机制,用spring.factories可以完成一个小组件的自动装配功能。在一般的业务场景下,你可能不太关心一个bean是如何注册到spring容器中的。只需将需要注册到容器中的bean声明为@Component,spring会自动扫描bean完成初始化并加载到spring上下文容器中。而当你在项目启动的时候需要提前做一个业务初始化工作,或者你在开发某个中间件需要完成自动组装的时候。您将声明自己的Configuration类,但您可能会面临多个相互依赖的bean。如果不加以控制,此时可能会报找不到依赖的错误。但是您显然已经将所有相关bean注册到spring上下文中。这时候就需要通过一些手段来控制springboot中bean的加载顺序。2.几个误区在正式讲怎么控制加载顺序之前,先说2个误区。在@Configuration标注的类中,写在前面的@Bean肯定会先被注册。这不存在。在之前spring的xml时代,没有写在前面的@Bean必须先加载的逻辑。因为xml不是逐步加载的,而是全部解析,然后进行依赖分析和注册。在springboot中只是省略了xml被解析成spring内部对象的过程,但是加载方式并没有太大变化。@Order注解可以用来控制加载顺序。严格来说,并不是所有的bean都可以通过@Order注解来控制。你给普通的方法或者类加上@Order注解是没有用的。那@Order能控制哪些bean的加载顺序呢,我们先看看官方的解释:{@code@Order}definesthesortorderforanannotatedcomponent.SinceSpring4.0,annotation-basedorderingissupportedformanykindsofcomponentsinSpring,evenforcollectioninjectionwheretheordervaluesofthetargetcomponentsaretakenintoaccount(eitherfromtheirtargetclassorfromtheir{@code@Bean}method).Whilesuchordervaluesmayinfluenceprioritiesatinjectionpoints,请注意它们不会影响单例启动顺序,这是由依赖关系和{@code@DependsOn}声明确定的正交问题(影响运行时确定的依赖关系图)。最初,@Order注解用于指定切面的优先级;4.0之后,增强了其功能,支持按顺序注入collection,指定,并特别指出它对实例的bean之间的顺序没有影响。目前使用比较多的有以下三点:控制AOP类的加载顺序,即@Aspect标记的类控制ApplicationListener实现类的加载顺序控制CommandLineRunner实现类的加载顺序3.如何控制3.1@DependsOn@DependsOn注解可以用来控制bean的创建顺序。此注解用于声明当前bean依赖于另一个bean。依赖bean由容器保证在当前bean被实例化之前被实例化。示例:@ConfigurationpublicclassBeanOrderConfiguration{@Bean@DependsOn("beanB")publicBeanAbeanA(){System.out.println("beanAinit");returnnewBeanA();}@BeanpublicBeanBbeanB(){System.out.println("beanBinit");返回newBeanB();}@Bean@DependsOn({"beanD","beanE"})publicBeanCbeanC(){System.out.println("beanCinit");returnnewBeanC();}@Bean@DependsOn("beanE")publicBeanDbeanD(){System.out.println("beanDinit");returnnewBeanD();}@BeanpublicBeanEbeanE(){System.out.println("beanEinit");returnnewBeanE();}}以上代码bean的加载顺序为:beanBinitbeanAinitbeanEinitbeanDinitbeanCinit@DependsOn的使用:直接或间接在类上标注@Component注解;直接或间接在方法上标注@Bean注解;在class级别使用@DependsOn注解只有在使用component-scanning方法时才有效,如果带有@DependsOn注解的class被XML使用,注解将被忽略,
