首页 > 解决方案 > Spring外部库bean初始化顺序

问题描述

我在我的应用程序中遇到了一个问题,不知何故我需要强制一个 bean A 在另一个 bean B 之前初始化。这些 bean 是由外部依赖项(不同的依赖项)提供的,所以我不能简单地用@DependsOn注释来做。
有没有可用的解决方案?

标签: javaspring

解决方案


我建立了一个简单的(模块化,maven)项目@DependsOn,并且在“外部组件”上使用注释没有遇到任何问题。只有几件事要完成:

  1. 确保A位于B.
  2. 确保B的应用程序上下文@ComponentScans (also) A
  3. 找出/猜测“逻辑 bean 名称”并在注释A中使用该值。@DependsOn..then@DependsOn按预期工作(也在“外部依赖项”上)。

该示例使用,但(我确信)配置详细信息适用于“无引导”环境/上下文。


并考虑 DependsOn 的 javadoc:

在 bean 不通过属性或构造函数参数显式依赖另一个 bean 而是依赖于另一个 bean 初始化的副作用的情况下很少使用。

@Autowired会给你同样的效果(用类似的努力),但类型安全/没有“名字猜测” - 我将它添加到示例中


返工:关于第三个项目(baz)的这个问题,您还有几个选项可以AB.

  1. 如果初始化AB简单(例如默认构造函数),您可以像这样在配置/应用程序中继续:

    import ...A;
    import ...B;
    ...
    @Configuration// @SpringBootApplication ..or idempotent
    public class MyConfig {
        ...
        @Bean("a")
        public A a() {
          return new A();
        }
    
        @Bean
        @DependsOn("a")
        public B b() {
          return new B();
        }
        ...
    }
    
  2. 如果(A 和 B 的)初始化不是微不足道的,但您可以参考现有的(外部)配置,那么这可行(重新定义自动装配的 bean,添加 dependsOn 注释):

    @Configuration
    @Import(value = {BConfig.class, AConfig.class})
    class MyConfig {
    
      @Bean("a")
      public A a(@Autowired A a) {
        return a;
      }
    
      @Bean
      @DependsOn("a")
      public B b(@Autowired B b) {
        return b;
      }
    }
    
  3. 您依赖组件扫描,并重新定义bean(使用dependsOn):

    @Configuration
    @ComponentScan(basePackageClasses = {B.class, A.class})
    class MyConfig {
        // same as 2.
    }
    
  4. ...

如果外部配置(2.、3.)定义了具有相同“名称”的 bean,则spring.main.allow-bean-definition-overriding属性必须设置为true(在 application.properties 或幂等中)。


推荐阅读