Spring 覆盖另一个模块的bean
Spring override bean of another module
在我的多模块项目中,我将集成测试作为单独的模块。该测试已将应用程序 jar 添加为依赖项。是否可以从集成测试中覆盖应用程序 bean 定义?
在应用程序中我有以下 Bean(标准 java 邮件发件人配置)
@Configuration
public class MailConfiguration {
@Bean
public JavaMailSender javaMailService() {
JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
//standard mail configuration using properties
}
}
现在我所有的集成测试都扩展了加载测试配置的 BaseIntegrationTest classess
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes = { AppTestConfiguration.class, MailTestConfiguration.class})
public class BaseIntegrationTest {
}
最后在我的 MailTestConfiguration 中我定义了另一个 JavaMailSender
@Primary
@Bean
@Profile(TestProfiles.MAIL_GREEN_SMTP)
public JavaMailSender javaMailService() {
JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
javaMailSender.setHost("localhost");
javaMailSender.setPort(3025);
return javaMailSender;
}
当我 运行 从应用程序本身进行测试时,它正在工作。当我 运行 来自另一个模块的测试时,bean 不会被覆盖。
我知道在应用程序内部定义的 AppConfiguration class 无法组件扫描集成测试配置 classes 所以我也加载 AppTestConfiguration。
@Configuration
@ComponentScan(basePackages = {"..."})
public class AppTestConfiguration extends AppConfiguration {
}
如何让它发挥作用?
您应该检查两件事:
- 当您 运行 来自另一个模块的测试时,是否启用了正确的 Spring 配置文件?
- 当您运行从另一个模块进行测试时,给定的配置是否在扫描路径中?
当然,我搞砸了配置文件。在我的 BaseIntegrationTest 中,我根据配置定义了活动配置文件。我还打印了哪个配置文件在那里得到解析(打印了正确的配置文件名称)
@BeforeClass
public static void init() {
System.setProperty(DEFAULT_PROFILES_PROPERTY_NAME, ProfileResolver.getActiveProfiles());
}
在你说服我它应该工作后,我重新检查了配置,发现我还在属性中添加了 spring.profiles.active。删除此配置后,一切都按预期工作。另一种方法是使用 AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME
而不是 AbstractEnvironment.DEFAULT_PROFILES_PROPERTY_NAME
在我的多模块项目中,我将集成测试作为单独的模块。该测试已将应用程序 jar 添加为依赖项。是否可以从集成测试中覆盖应用程序 bean 定义?
在应用程序中我有以下 Bean(标准 java 邮件发件人配置)
@Configuration
public class MailConfiguration {
@Bean
public JavaMailSender javaMailService() {
JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
//standard mail configuration using properties
}
}
现在我所有的集成测试都扩展了加载测试配置的 BaseIntegrationTest classess
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes = { AppTestConfiguration.class, MailTestConfiguration.class})
public class BaseIntegrationTest {
}
最后在我的 MailTestConfiguration 中我定义了另一个 JavaMailSender
@Primary
@Bean
@Profile(TestProfiles.MAIL_GREEN_SMTP)
public JavaMailSender javaMailService() {
JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
javaMailSender.setHost("localhost");
javaMailSender.setPort(3025);
return javaMailSender;
}
当我 运行 从应用程序本身进行测试时,它正在工作。当我 运行 来自另一个模块的测试时,bean 不会被覆盖。
我知道在应用程序内部定义的 AppConfiguration class 无法组件扫描集成测试配置 classes 所以我也加载 AppTestConfiguration。
@Configuration
@ComponentScan(basePackages = {"..."})
public class AppTestConfiguration extends AppConfiguration {
}
如何让它发挥作用?
您应该检查两件事:
- 当您 运行 来自另一个模块的测试时,是否启用了正确的 Spring 配置文件?
- 当您运行从另一个模块进行测试时,给定的配置是否在扫描路径中?
当然,我搞砸了配置文件。在我的 BaseIntegrationTest 中,我根据配置定义了活动配置文件。我还打印了哪个配置文件在那里得到解析(打印了正确的配置文件名称)
@BeforeClass public static void init() { System.setProperty(DEFAULT_PROFILES_PROPERTY_NAME, ProfileResolver.getActiveProfiles()); }
在你说服我它应该工作后,我重新检查了配置,发现我还在属性中添加了 spring.profiles.active。删除此配置后,一切都按预期工作。另一种方法是使用 AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME
而不是 AbstractEnvironment.DEFAULT_PROFILES_PROPERTY_NAME