[英]How to set Spring Active Profiles Pragmatically from a configuration class?
在我正在開發的項目中,我們有一些舊的依賴項,它們定義了自己的spring bean,但需要從主應用程序初始化。 這些bean都是使用彈簧配置文件構建的,即生產代碼的“默認”和測試代碼的“測試”。 我們希望不再使用彈簧配置文件,而只需使用@import顯式連接我們的上下文。
我們的想法是封裝所有這些舊的依賴項,以便其他組件不需要關心彈簧配置文件。 因此,從測試的角度來看,應用程序上下文設置可以描述如下:
@ContextConfiguration(classes = {TestContext.class})
@RunWith(SpringJUnit4ClassRunner.class)
public class MyTest {
//tests
}
TestContext進一步指向兩個類,其中一個類封裝了舊的依賴項:
@Configuration
@Import(value = {OldComponents.class, NewComponents.class})
public class TestContext {
//common spring context
}
為了封裝舊組件對配置文件的需求,OldComponents.class如下所示:
@Configuration
@Import(value = {OldContext1.class, OldContext2.class})
public class OldComponents {
static {
System.setProperty("spring.profiles.active", "test");
}
}
這里的問題是靜態塊似乎沒有及時執行。 運行mvn clean install時,測試會收到IllegalStateException,因為無法加載ApplicationContext。 我已經驗證了靜態塊被執行了,但是看起來OldContext1和OldContext2(它們依賴於配置文件)此時已經被加載了,這意味着它已經太晚了。
令人沮喪的是,IntelliJ以這種方式運行測試。 然而,Maven沒有。 有沒有辦法在保持封裝的同時強制使用這些配置文件? 我試過創建一個中間上下文類,但它沒有解決問題。
如果我們在測試類上使用注釋@ActiveProfiles,它運行得很好但是這種方法失敗了。 當然,我們希望在生產中實現相同的目標,這意味着如果我們無法封裝對配置文件的需求,則需要在web.xml中進行配置。
如果您的配置類繼承了AbstractApplicationContext,則可以調用:
getEnvironment().setActiveProfiles("your_profile");
例如:
public class TestContext extends AnnotationConfigWebApplicationContext {
public TestContext () {
getEnvironment().setActiveProfiles("test");
refresh();
}
}
希望能幫助到你。
這definietly似乎OldContext1
和OldContext2
正在類加載和靜態塊初始化之前OldComponents
執行。
雖然我無法解釋為什么你的IDE和Maven之間存在差異(要做到這一點需要深入了解一些,如果不是全部的話):spring 3.x上下文初始化,maven surefire插件,SpringJunit4ClassRunner和內部IntelliJ測試運行器),我可以推薦試試嗎?
@Configuration
@Import(value = {UseTestProfile.class, OldContext1.class, OldContext2.class})
public class OldComponents {
// moved the System.setProperty call to UseTestProfile.class
}
和
@Configuration
public class UseTestProfile {
static {
System.setProperty("spring.profiles.active", "test");
}
}
如果我正確理解您的問題,應首先加載類UseTestProfile
(您可能想要調查一種方法來保證這一點?)並且導入列表中的其他兩個類應該具有正確初始化所需的系統設置。
希望這可以幫助...
你需要確保,環境首先生效。這就是我的方式:
@Component
public class ScheduledIni {
@Autowired
private Environment env;
@PostConstruct
public void inilizetion() {
String mechineName = env.getProperty("MACHINE_NAME");
if ("test".equals(mechineName) || "production".equals(mechineName) {
System.setProperty("spring.profiles.default", "Scheduled");
System.setProperty("spring.profiles.active", "Scheduled");
}
}
}
在調度程序中添加注釋Prodile
和DependsOn
以使其工作。
@DependsOn("scheduledIni")
@Profile(value = { "Scheduled" })
@Component
在類中使用@profile注釋來加載如下所示的配置
@Configuration
@Profile("test")
public class UseTestProfile {
}
並在屬性文件中或作為運行時參數設置屬性spring.profiles.active
的值
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.