博客
关于我
如果你还不知道如何控制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/

    你可能感兴趣的文章
    python中import os_Python:相对导入与绝对导入(import)、os.path、__file__
    查看>>
    python中is和==操作符
    查看>>
    Python中range对象的使用以及打印九九乘法表
    查看>>
    Python中set.discard和set.remove方法之间的运行时差异?
    查看>>
    python中tkinter中value_输入字段中的python Tkinter get()值
    查看>>
    Python中wx.FlexGridSizer
    查看>>
    Python中xPath技术和BeautifulSoup的使用
    查看>>
    python中yield的用法详解——最简单,最清晰的解释
    查看>>
    python中‘set.intersection()‘的算法是什么?
    查看>>
    Python中一个图形中的多个绘图
    查看>>
    python中一个好的持久同步队列
    查看>>
    Python中不准确的对数
    查看>>
    python中什么是实例方法_在Python中创建实例方法对象的不同方法
    查看>>
    Python中使用cutecharts实现简单的手绘风格的图表
    查看>>
    python中使用dxfgrabber,解析dxf文件信息生成obj文件
    查看>>
    Python中使用ncmbot玩转网易云音乐
    查看>>
    Python中使用PIL快速实现二值图
    查看>>
    Python中使用PIL快速实现灰度图
    查看>>
    Python中使用pip install ncmbot时各种错误解决办法
    查看>>
    Python中使用requests和parsel爬取喜马拉雅电台音频
    查看>>