具有重复bean和@Order注释的Spring依赖项注入

时间:2019-06-20 14:05:51

标签: java spring dependency-injection spring-bean

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

  • 一个豆可以定义一个以上的豆
  • 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
}

RewardsConfig

@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中定义的值生效。

1 个答案:

答案 0 :(得分:0)

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

@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注释都无效。