2013-07-28 33 views
1

我正在努力尋找解決方案,以根據不同的環境從不同的地方訪問配置文件(devprod)。從不同位置加載屬性

這是我的項目的大致佈局。

│ pom.xml 
    └───src 
     └───main 
      ├───java 
      │  ConfigurationLoader.java 
      ├───resources 
      │  conf1.properties 
      └───webapp 
       │ web.xml 
       └───WEB-INF 

ConfigurationLoader是一個自我描述類和被認爲是一些純單,整個應用程序靜態可用。

dev環境應該從classpath中加載根conf1.properties,但在prod ENV應該在容器的根文件夾(例如:%TOMCAT_HOME%\bin)找到它們。

如何正確實施ConfigurationLoader這種選擇性屬性加載?

感謝

UPD:

我更感興趣的是ConfigurationLoader實施和屬性文件的位置。問題是,如何找到這些文件ConfigurationLoader。喜歡的東西:

String path = "/conf1.properties"; 
File confFile; 
switch (environment) { 
    case "dev": //classpath 
    URI location = ConfigurationLoader.class.getResource(path).toURI(); 
    confFile = new File(location); 
    break; 
    case "prod": //root (?) 
    confFile = new File(path); 
    break; 
} 
Properties p = new Properties(confFile); 

又來了幾個問題:

  1. 我應該如何通過環境變量的代碼的Maven(在配置文件中定義或其他)?我不想過濾java類,並且可能僅用環境條目預加載另一個屬性文件。另外,我不認爲我能夠在生產平臺上修改系統屬性(-Denv=whatever)。

  2. 如果什麼樣的屬性文件需要包含一些資源路徑的其他系統組件(例如:applicationContext.xml春天也應該安排在類路徑dev或在bin Tomcat的文件夾)進行訪問?這些路徑應該是什麼樣的,我需要如何在我的代碼中解決這些問題,從而避免代碼重複的ConfigurationLoader部分?

是否有機會更多地在maven中解決它,而在代碼中更少,或存在其他方法?

+0

你能不能定義環境的2種,並用if語句什麼環境現狀您正在使用的那一刻檢查?這可能在你的設置文件或類似的東西。 – Reshad

回答

1

雖然有problably了多種解決方案,我寧願以下幾點:實現了相同的接口(例如ConfigurationLoader接口)會從類路徑和一個會處理處理配置

使用兩個不同的類,一個文件大小寫。爲您的應用程序使用屬性文件(例如,app.properties),這些屬性文件將由您的構建版創建(prod和dev不同的值),並且始終位於classpath中的相同位置,例如根包。在這個文件中,你將有以下特性:

config.loader.class=com.mycompany.ClasspathConfigurationLoader # or FileConfigurationLoader for prod environment 
config.loader.resource.classpath=resources/conf1.properties # use classloader.getResourceAsStream() to load this resource 
config.loader.resource.file=/path/to/tomcat/home/bin/conf1.properties 

現在,因爲您的裝載機是單身,你將有一個靜態的塊,將讀取屬性文件,並基於第一屬性將決定什麼類型的實例來創建爲ConfigurationLoader類。 然後,每種不同類型的實例都可以使用其他屬性來決定要加載的資源。

+0

嗨,謝謝你,那是我現在的解決方案,但是引用來自該屬性文件的其他資源存在問題。我想我需要以ConfigurationLoader的幾種實現方式重複加載這些資源。看到我的更新 – glaz666

2

喜歡這個問題!我們有完全相同的問題,並按如下方式解決。我們項目的結構基本相同,除了額外的external-resources-{username}文件夾:

│ pom.xml 
    └───src 
     └───main 
      ├───java 
      │  ConfigurationLoader.java 
      ├───external-resources-drvdijk 
      │  conf.properties 
      ├───resources 
      │  conf.default.properties 
      └───webapp 
       │ web.xml 
       └───WEB-INF 

然後,在pom.xml,我們包括:

<profiles> 
    <profile> 
     <id>development</id> 
     <build> 
      <resources> 
       <resource> 
        <directory>src/main/external-resources-${user.name}</directory> 
        <filtering>true</filtering> 
       </resource> 
      </resources> 
     </build> 
    </profile> 
</profiles> 

這使每個團隊成員能夠創建自己的external-resources-{username}目錄,啓用Maven配置文件和構建。我們版本的ConfigurationLoader.java(實際上在我們的項目中被稱爲不同)將首先讀取conf.default.properties文件中的所有屬性(它們也可以是「空」屬性,例如db.username =)。ConfigurationLoader.java然後,它會加載Maven配置文件包含的conf.properties或在應用程序服務器的lib目錄中,並使用conf.properties中找到的所有屬性覆蓋conf.default.properies中找到的所有現有屬性。

在我們的conf.default.properties中,我們明確列出了我們的應用程序可以處理的所有屬性。如果在加載所有屬性(包括conf.properties)之後有一些丟失(或者發現了一些未知的屬性),那麼應用程序會引發很多錯誤並拒絕啓動。

希望這有助於:)

+0

+1擊敗了我。配置文件是要走的路。它們可以在POM中聲明,也可以在設置文件的外部聲明並按需啓用。另一個例子見:http://stackoverflow.com/questions/15120229/best-practice-for-defining-machine-specific-resources-in-maven-builds/15123042#15123042 –

+0

嗨,謝謝你的回答。請參閱我的upd以獲取更多描述性評論。 – glaz666