博客
关于我
如果你还不知道如何控制springboot中bean的加载顺序,那你一定要看此篇
阅读量:412 次
发布时间:2019-03-06

本文共 2784 字,大约阅读时间需要 9 分钟。

为什么需要控制加载顺序

在Spring Boot项目中,默认情况下Spring会自动扫描并加载所有标注了@Component的类,将它们注册到应用上下文中。这种自动化的特性极大地简化了配置流程,但在某些场景下,我们可能需要对Bean的加载顺序进行控制,以确保依赖关系的正确性和应用的稳定运行。

常见误区

在了解如何控制Bean的加载顺序之前,让我们先澄清一些常见的误区。

  • @Configuration类中@Bean的顺序决定了加载顺序

    这个说法是错误的。在Spring Boot中,@Configuration类中的@Bean注解并不会决定Bean的加载顺序。Spring在处理配置时,并不严格按照文件中的顺序进行解析,而是根据依赖关系和@DependsOn注解进行动态加载。

  • @Order注解可以控制所有Bean的加载顺序

    实际上,@Order注解并不是用来控制所有Bean的加载顺序的。在Spring中,这个注解主要用于控制切面(Aspect)的优先级,或者在集合注入时指定Bean的顺序。对于普通的Bean来说,@Order注解并没有直接的应用场景。

  • 需要注意的是,虽然@Order本身并不是用来控制Bean的整体加载顺序,但它在某些特定场景中确实可以发挥作用,例如控制ApplicationListener或CommandLineRunner的加载顺序。

    如何控制Bean的加载顺序

    在Spring Boot中,控制Bean的加载顺序主要有以下几种方法。

    1. 使用@DependsOn注解

    @DependsOn注解可以用来声明当前Bean依赖于其他Bean。Spring会确保所依赖的Bean在当前Bean实例化之前被实例化。这个注解非常有用,尤其是在处理有依赖关系的Bean时。

    以下是一个示例:

    @Configurationpublic class BeanOrderConfiguration {    @Bean    @DependsOn("beanB")    public BeanA beanA() {        System.out.println("Bean A 初始化");        return new BeanA();    }    @Bean    public BeanB beanB() {        System.out.println("Bean B 初始化");        return new BeanB();    }    @Bean    @DependsOn({"beanD", "beanE"})    public BeanC beanC() {        System.out.println("Bean C 初始化");        return new BeanC();    }    @Bean    @DependsOn("beanE")    public BeanD beanD() {        System.out.println("Bean D 初始化");        return new BeanD();    }    @Bean    public BeanE beanE() {        System.out.println("Bean E 初始化");        return new BeanE();    }}

    在上述配置中,BeanB会在BeanA之前被初始化,BeanE会在BeanC和BeanD之前被初始化。因此,实际的加载顺序是:

    Bean B → Bean A → Bean E → Bean D → Bean C

    2. 参数注入

    在Spring Boot中,@Bean注解的方法可以接收参数。Spring会自动为参数寻找匹配的Bean实例,并在参数注入之前将其初始化。

    以下是一个示例:

    @Beanpublic BeanA beanA(BeanB demoB) {    System.out.println("Bean A 初始化");    return new BeanA();}@Beanpublic BeanB beanB() {    System.out.println("Bean B 初始化");    return new BeanB();}

    在这种情况下,BeanB会在BeanA之前被初始化,因为它作为参数被注入到BeanA中。

    需要注意的是,如果你希望BeanA优先于BeanB加载,可以通过使用@Qualifier注解指定BeanB的名称。

    3. 利用Spring容器的扩展点

    Spring容器的生命周期扩展点允许我们在Bean的初始化过程中插入自定义逻辑。虽然这些扩展点的加载顺序由Spring本身控制,但我们可以利用这一点来实现对某些特定Bean的加载顺序控制。

    4. 使用@AutoConfigureOrder注解

    @AutoConfigureOrder注解可以用于指定Configuration类的加载顺序。需要注意的是,它只能影响外部依赖的Configuration类,而不是项目内部的Configuration类。

    以下是一个示例:

    @Configuration@AutoConfigureOrder(10)public class BeanOrderConfiguration1 {    @Bean    public BeanA beanA() {        System.out.println("Bean A 初始化");        return new BeanA();    }}@Configuration@AutoConfigureOrder(1)public class BeanOrderConfiguration2 {    @Bean    public BeanB beanB() {        System.out.println("Bean B 初始化");        return new BeanB();    }}

    在这种情况下,BeanOrderConfiguration2会在BeanOrderConfiguration1之前被加载,因为@AutoConfigureOrder注解只影响外部依赖的Configuration类。

    总结

    在实际应用中,控制Bean的加载顺序通常可以通过@DependsOn注解、参数注入、利用Spring容器的扩展点等方式实现。每种方法都有其适用的场景,选择哪种方式取决于具体的需求和项目结构。

    如果你对Spring Boot的其他特性感兴趣,可以关注我的技术博客,获取更多技术干货!

    转载地址:http://cyxkz.baihongyu.com/

    你可能感兴趣的文章
    python3.6 ubuntu部署nginx、 uwsgi、 django
    查看>>
    Python3.6.3中,functools似乎不能用
    查看>>
    python3.6.5+cuda9+cudnn7.1+win10+tensorflow-gpu1.9.0下载配置
    查看>>
    python3.6使用pickle序列化class
    查看>>
    python3.6入门到高阶(全栈) day027 网络通信协议 osi七层模型
    查看>>
    Python3.6属性错误:模块‘;异步没有属性‘;运行‘;
    查看>>
    python3.6版本中的python-weka-wrapper安装失败,错误代码为%1
    查看>>
    Python3.7安装cv2踩过的坑
    查看>>
    python写txt文件
    查看>>
    python关于sorted排序函数详细解析 附实战代码(全)
    查看>>
    python3.8调用m文件,调用matlab
    查看>>
    python3.9新特性_Python 3.9 新特性速览
    查看>>
    Python3.x:遍历select下拉框获取value值
    查看>>
    python360百科_11月编程排行榜:Python超过Java成第二
    查看>>
    Python关于Paginator分页函数详细解析 附实战代码
    查看>>
    python3、ipython3、setup-tools、pip等环境搭建详细总结
    查看>>
    python3下使用cv2.imwrite存储带有中文路径图片或者绝对路径图片
    查看>>
    python3与django中@property详解
    查看>>
    python3中如何表示无穷大
    查看>>
    Python3中提示:no module named 'wxpy'
    查看>>