`

Maven 動態配置properties (resources)

阅读更多

    本文只作記錄和參考,希望對自己或者各位路人都有多少價值。

 

    在實際開發過程中,配置信息會因為不同環境而有所不同。而過多的人工干預,會增加工作量和錯誤率。現在記錄的是如何使用maven快速安全地切換配置信息而不需要多餘的人工修改干預。我們就以最常見的數據庫信息切換作為例子。

 

   Project Structure:

 

   ------src

            | ------ main

                          | ------java

                                        | ------ 省略,此處不是重點

                          | ------resources

                                        | ------ db.properties

                          | ------filters

                                        | ------ db-dev.properties

                                        | ------ db-prod.properties

            | ------ test

                          | ------java

                                        | ------ 省略,此處不是重點

                          | ------resources

                                        | ------ db.properties

                          | ------filters

                                        | ------ db-dev.properties

                                        | ------ db-prod.properties

   ------tags

   ------target

   ------trunk

   ------pom.xml

 

     項目結構就是最常見的maven project 結構。在此,留意filters, 這個是本文的重點。

     先來簡述一下。

      resources/db.properties -- 程序會從中讀取數據庫信息。對於不同的環境,dev/prod 信息不同。

      filters/db-dev.properties  -- dev 環境的數據庫信息

      filters/db-prod.properties  -- prod 環境的數據庫信息

 

     用一句話來概括, 就是字符的替換。 把db.properties的wildcard替換成dev/prod 的相應值。

 

     db.properties 的內容和dev/prod的內容,在格式上是一樣的。

   

 

#db.properties
db.username=${db.username}
db.password=${db.password}
application.name=${project.name}

 

#db-dev
db.username=dev
db.password=dev-pwd

 

#db-prod
db.username=prod
db.password=prod-pwd

 

 

    至此,準備工作已經完成。接下來是maven的配置。

 

    

<build>

    <filters>
         <filter>${project.basedir}/src/main/filters/db-${env}.properties</filter>
    </filters>
    <resources>
 	<resource>
        	<directory>src/main/resources</directory>
		<filtering>true</filtering>
	</resource>
    </resources>
</build>

 

 

     解釋一下。

     filters 的意義在於,表明使用該文件(s)中定義的值來替換目標字符。(From whom)

     resources/resource ,表示替換會對在哪個目錄下的文件作用。 (To whom)

 

    大家可能也會對${env} 有疑問。這個就是動態配置的關鍵之一。"profiles"

    在pom.xml 中,有以下聲明:

    

<profiles>
    <profile>
	<id>dev</id>
        <properties>
	   <env>dev</env>
	</properties>
    </profile>
    <profile>
	<id>prod</id>
        <properties>
	    <env>prod</env>
        </properties>
    </profile>
</profiles>

  

     此處聲明了2個 profiles. 這個profile 其實是可以定義任意的屬性,甚至可以把數據庫的信息定義在上面。不過,這麼做是不推薦的,靈活性太低。相反,僅定義2個profiles, 把並把對應的信息放入相應的properties會使的構建更加靈活和安全。畢竟,這些人手寫錯打錯導致各式各樣的問題屢見不鮮。當這些profile 被激活使用之後,就會初始化一個變量 , env。並且在filter下面的${env}會被替換成真實的值。這樣,就可以動態更改配置。

 

    把pom配置好之後,就可以嘗試編譯,體會一下這個形式的動態配置。

 

 

mvn clean compile

 

 

    此時,會出現以下錯誤: 

 

    

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:2.6:resources
        (default-resources) on project mvn.renew: Error loading property file 
         'D:\TestingDir\mavenBuildDemo\src\main\filters\db-${env}.properties' -> [Help
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.

 

 

    為什麼? 因為這個時候還未有選擇 profile, 所以 ${env} 並沒有被初始化。我們應該用以下命令來構建:

    

 

mvn clean compile -Pdev

 

 

   -P 就是選擇對應在pom中聲明了的profile。

 

    

D:\TestingDir\mavenBuildDemo>mvn clean compile -Pdev
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building mvn.renew 1.0
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ mvn.renew ---
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ mvn.renew ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Copying 1 resource
[INFO]
[INFO] --- maven-compiler-plugin:2.5.1:compile (default-compile) @ mvn.renew ---
[INFO] Compiling 1 source file to D:\TestingDir\mavenBuildDemo\target\classes
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.482 s
[INFO] Finished at: 2016-04-09T20:52:55+08:00
[INFO] Final Memory: 11M/107M
[INFO] ------------------------------------------------------------------------

 

 

    構建成功了。那麼怎麼驗證呢 ? 或許大家都知道,compile之後所有文件,包括 class and properties, 都會被放到 target/classes 下面。那麼我們就去target/classes 下面找。我們會找到一個 db.properties文件,打開檢查:

     

db.username=dev
db.password=dev-pwd
application.name=mvn.renew

 

 

   成功匹配 !!

 

   但是如果項目很大,每次構建都相當耗時,那麼,有沒有方法只更新配置文件而不重新編譯?

   這個問,肯定是有的啦 !

 

mvn process-resources -Pprod

 

     用process-resources, 這樣,只會更新配置文件,而不會重新編譯項目。

     再去看一下properties, 已經變成了 prod 的信息了。

    

 

db.username=prod
db.password=prod-pwd
application.name=mvn.renew

 

 

    本文到此,已經完結。大家有所感受了么? 

    在自己記錄的時候也喜歡在大家需要的時候給一點啟示或幫助.

   

    

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics