欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Maven 動態配置properties (resources)

程序员文章站 2022-05-10 17:26:15
...

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

 

    在實際開發過程中,配置信息會因為不同環境而有所不同。而過多的人工干預,會增加工作量和錯誤率。現在記錄的是如何使用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

 

 

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

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