2012-05-19 45 views
3

我有一個Spring 3.1應用程序。比方說,它有以下內容的XML:根據配置文件在Spring中加載屬性文件

<context:property-placeholder location="classpath:somename.properties" /> 

<context:property-placeholder location="classpath:xxx.properties" /> 

我想總是加載some.properties(假設它存在),而是由一些名替換第二位持有人的XXX部分取決於活動配置文件。我試過這個:

<beans profile="xx1"> 
    <context:property-placeholder location="classpath:xx1.properties" /> 
</beans> 

<beans profile="xx2"> 
    <context:property-placeholder location="classpath:xx2.properties" /> 
</beans> 

此外,這兩個文件都具有相同的鍵但不同的值的屬性。

但是它沒有工作,因爲一些後來的bean有一個屬性的佔位符,這個屬性的鍵在xx1.properties(和xx2.properties)中定義,這使得Spring抱怨在應用程序上下文中找不到該鍵。

+4

您是否使用maven構建您的項目?我相信Maven有一種使用過濾器對屬性文件名進行令牌替換的方法。 – jeff

+0

我確實使用Maven,但似乎很奇怪Spring沒有提供它自己的方式來做到這一點。 – Luciano

回答

1

我已決定提交併回答此問題,因爲它尚未被接受。它可能不是你正在尋找的具體內容,但它適用於我。另外請注意,我使用新的註釋驅動配置,但它可以移植到xml配置。

我有一個屬性文件的每個環境(dev.properties,test.properties等)

我然後有一個RootConfig類,其是用於所有配置的類。這個類中所有的註解都是兩個註解:@Configuration和@ComponentScan(basePackageClasses = RootConfig.class)。 這告訴它掃描與它相同的包中的任何東西。

然後有一個配置包含所有我正常的配置,無論在哪裏。與上面的根配置類相同的軟件包中的每個環境也有一個配置。

環境的具體配置是簡單地認爲有以下注釋將它指向環境的具體屬性文件標記類:

@Configuration 
@PropertySource("classpath:dev.properties") 
@Import(NormalConfig.class) 
@Profile("dev") 

進口告訴它在正常的配置類帶上。但是當它進入那裏時,它會設置環境特定的屬性。

+0

正如你可以從日期推算出來的那樣,我不再有這個問題。我無法測試你的答案,但似乎接近我所尋找的。 – Luciano

4

你可以這樣做:

<context:property-placeholder location="classpath:${spring.profiles.active}.properties" /> 

它工作正常,但在同時使用多個配置文件時,可能不適合。


在聲明2個財產佔位符,如果第一個不包含所有的應用程序鍵,你應該把忽略無法解決的= TRUE的屬性,以便於第二個佔位符都可以使用。 我不確定它是否是您想要做的事情,如果您希望xx1和xx2配置文件在同一時間內處於活動狀態,則可能會這樣做。

請注意,聲明2個像這樣的屬性佔位符使它們是獨立的,並且在xx2.properties的聲明中,不能重用xx1.properties的值。


如果您需要更先進的東西,您可以在應用程序啓動時註冊您的PropertySources。

的web.xml

<context-param> 
    <param-name>contextInitializerClasses</param-name> 
    <param-value>com.xxx.core.spring.properties.PropertySourcesApplicationContextInitializer</param-value> 
    </context-param> 

文件創建:

public class PropertySourcesApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> { 

    private static final Logger LOGGER = LoggerFactory.getLogger(PropertySourcesApplicationContextInitializer.class); 

    @Override 
    public void initialize(ConfigurableApplicationContext applicationContext) { 
    LOGGER.info("Adding some additional property sources"); 
    String profile = System.getProperty("spring.profiles.active"); 
    // ... Add property sources according to selected spring profile 
    // (note there already are some property sources registered, system properties etc) 
    applicationContext.getEnvironment().getPropertySources().addLast(myPropertySource); 
    } 

} 

一旦你做到了,你只需要在您的上下文中添加:

<context:property-placeholder/> 

恕我直言,它的處理彈簧屬性的最佳方法,因爲你不再在任何地方聲明本地屬性,你可以通過程序控制發生了什麼事情,並且可以在xx2.properties中使用屬性來源xx1值。


在工作中,我們正在使用它,它很好地工作。我們註冊了3個其他財產來源: - 基礎設施:由Puppet提供 - 個人資料:根據個人資料加載的不同屬性。 - 通用:包含默認值,當所有配置文件共享相同的值等...

相關問題