【问题标题】:Spring dependency injection with duplicate beans and @Order annotation带有重复bean和@Order注解的Spring依赖注入
【发布时间】:2019-11-03 09:07:56
【问题描述】:

当有多个具有相同名称/类型的 bean 时,我对 Spring 中的 DI 注入机制感到有些困惑。 根据 Pivotal 的“核心 Spring”课程的考试幻灯片,Spring 对相同 bean 的行为可以归结为:

  • 可以多次定义同一个 bean
  • Spring 注入最后定义的 bean
  • 使用@Order,可以修改加载机制(以及最后加载哪个bean)

但是,在下面的示例中,Spring 将忽略任何 @Order 注释并从 @Import 语句中最后提到的 Config 类中注入 bean。 因此,我想知道 @Import 注释中的配置类的顺序是否会覆盖任何 @Order 注释。还是我错过了另一个重要的点? 任何提示都非常感谢。感谢堆栈溢出!

主配置类

@Configuration
@Import({RogueConfig.class,RewardsConfig.class})
public class TestInfrastructureConfig {
  // nothing interesting here, just importing configs
}

奖励配置

@Configuration
@Order(1)
public class RewardsConfig {
    @Bean
    public RewardNetwork rewardNetwork() {
        System.out.println("This Bean has been loaded from: " + this.getClass().getName());
        return new RewardNetworkImpl(null, null, null);
    }
}

RogueConfig

@Configuration
@Order(2)
public class RogueConfig {
    @Bean
    public RewardNetwork rewardNetwork() {
        System.out.println("This Bean has been loaded from: " + this.getClass().getName());
        return new RewardNetworkImpl(null, null, null);
    }
}

测试类

public class RewardNetworkTests {

    ApplicationContext applicationContext;

    @BeforeEach
    void setUp() {
        applicationContext = SpringApplication.run(TestInfrastructureConfig.class);
    }

    @Test
    void injectingRewardNetworkBeanWithOrdering() {
        RewardNetwork rewardNetwork = applicationContext.getBean(RewardNetwork.class);
        assertNotNull(rewardNetwork);
    }
}

无论我分配什么值@Order,或者如果我使用排序,结果将始终是:

This Bean has been loaded from: config.RewardsConfig$$EnhancerBySpringCGLIB$$62461c55

改变这一点的唯一方法是修改我的TestInfrastructureConfig 中的 Import 注释,如下所示:

@Import({RewardsConfig.class,RogueConfig.class}),产生:

This Bean has been loaded from: config.RogueConfig$$EnhancerBySpringCGLIB$$6ca7bc89

我想知道需要做什么才能让@Order 中定义的值生效。

【问题讨论】:

    标签: java spring dependency-injection spring-bean


    【解决方案1】:

    我已经能够通过直接加载配置来让 Spring 使用 @Order 注释(即无需绕道使用 @Import@Configuration 类):

    @SpringJUnitConfig({RogueConfig.class, RewardsConfig.class})
    public class CdiTest {
    
        @Test
        public void testCdiWithIdenticalBeans(@Autowired RewardNetwork rewardNetwork) {
            assertThat(rewardNetwork).isNotNull();
        }
    }
    

    使用 RogueConfig 类上的 @Order(2) 注释,这个 bean 最后被加载,如 stdout 所示:

    This Bean has been loaded from: config.RogueConfig$$EnhancerBySpringCGLIB$$552b937f

    似乎在配置类中使用@Import 时,它会按照注解中提供的顺序加载bean 定义,从而使各个配置类上的任何@Order 注解都无用。

    【讨论】:

      猜你喜欢
      • 2012-04-25
      • 2012-08-02
      • 2020-04-14
      • 2023-03-09
      • 1970-01-01
      • 2011-11-06
      • 2014-06-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多