Spring 带有重复 bean 和 @Order 注释的依赖注入
Spring dependency injection with duplicate beans and @Order annotation
当多个 bean 具有相同的 name/type 时,我对 Spring 中的 DI 注入机制有些困惑。
根据 Pivotal 的 "Core Spring" 课程的考试幻灯片,Spring 对相同 bean 的行为可以归结为:
- 一个人可以多次定义同一个 bean
- Spring 注入最后定义的 bean
- 使用
@Order
,可以修改加载机制(以及最后加载哪个 bean)
但是,在下面的示例中,Spring 将忽略任何 @Order
注释并从 @Import
语句中最后提到的 Config class 中注入 bean。
因此,我想知道 @Import
注释中配置 classes 的顺序是否会覆盖任何 @Order
注释。还是我错过了另一个重要的点?
任何提示都非常感谢。感谢 Stack Overflow!
主要配置class
@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);
}
}
测试class
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$461c55
更改此设置的唯一方法是修改我的 TestInfrastructureConfig
中的导入注释,如下所示:
@Import({RewardsConfig.class,RogueConfig.class})
,产生:
This Bean has been loaded from: config.RogueConfig$$EnhancerBySpringCGLIB$ca7bc89
我想知道需要做什么才能使 @Order
中定义的值生效。
我已经能够 Spring 通过直接加载配置来使用 @Order
注释(即不用绕过 @Configuration
class 使用 @Import
):
@SpringJUnitConfig({RogueConfig.class, RewardsConfig.class})
public class CdiTest {
@Test
public void testCdiWithIdenticalBeans(@Autowired RewardNetwork rewardNetwork) {
assertThat(rewardNetwork).isNotNull();
}
}
使用 RogueConfig class 上的 @Order(2)
注释,这个 bean 最后加载,如标准输出所示:
This Bean has been loaded from: config.RogueConfig$$EnhancerBySpringCGLIB$2b937f
似乎在配置 classes 中使用 @Import
时,它将按照注释中提供的顺序加载 bean 定义,从而在相应的配置 @Order
上进行注释 class没用。
当多个 bean 具有相同的 name/type 时,我对 Spring 中的 DI 注入机制有些困惑。 根据 Pivotal 的 "Core Spring" 课程的考试幻灯片,Spring 对相同 bean 的行为可以归结为:
- 一个人可以多次定义同一个 bean
- Spring 注入最后定义的 bean
- 使用
@Order
,可以修改加载机制(以及最后加载哪个 bean)
但是,在下面的示例中,Spring 将忽略任何 @Order
注释并从 @Import
语句中最后提到的 Config class 中注入 bean。
因此,我想知道 @Import
注释中配置 classes 的顺序是否会覆盖任何 @Order
注释。还是我错过了另一个重要的点?
任何提示都非常感谢。感谢 Stack Overflow!
主要配置class
@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);
}
}
测试class
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$461c55
更改此设置的唯一方法是修改我的 TestInfrastructureConfig
中的导入注释,如下所示:
@Import({RewardsConfig.class,RogueConfig.class})
,产生:
This Bean has been loaded from: config.RogueConfig$$EnhancerBySpringCGLIB$ca7bc89
我想知道需要做什么才能使 @Order
中定义的值生效。
我已经能够 Spring 通过直接加载配置来使用 @Order
注释(即不用绕过 @Configuration
class 使用 @Import
):
@SpringJUnitConfig({RogueConfig.class, RewardsConfig.class})
public class CdiTest {
@Test
public void testCdiWithIdenticalBeans(@Autowired RewardNetwork rewardNetwork) {
assertThat(rewardNetwork).isNotNull();
}
}
使用 RogueConfig class 上的 @Order(2)
注释,这个 bean 最后加载,如标准输出所示:
This Bean has been loaded from: config.RogueConfig$$EnhancerBySpringCGLIB$2b937f
似乎在配置 classes 中使用 @Import
时,它将按照注释中提供的顺序加载 bean 定义,从而在相应的配置 @Order
上进行注释 class没用。