Apache Maven 使用 profile 和 filtering 实现多种环境下的资源配置管理
http://archboy.org/2012/05/21/apache-maven-profile-filtering-multiple-build-environments/
構建項目時可能會遇到在測試(如單元測試)、開發、模擬、生產等不同環境下需要不同配置(properties、xml)或資源(jpg、png、mp3)的情況。比如常見的數據庫連接(即?jdbc url)的值,在不同的環境下可能有如下幾種值:
- 測試環境:jdbc:mysql://localhost:3306/foobar_test
- 開發環境:jdbc:mysql://localhost:3306/foobar_dev
- 模擬環境:jdbc:mysql://192.168.1.11:3306/foobar
- 生產環境:jdbc:mysql://192.168.1.10:3306/foobar
或者同樣是生產環境,針對(產品)交付給A公司客戶的與交付給B公司客戶的需要不同配置或者資源,比如產品界面中的公司名稱、公司LOGO等。
又或者針對不同的操作系統(如 Windows,Linux)需要為某個配置設定不同的文件路徑。
可見,在不同的軟件開發生命周期階段、不同的最終客戶(用戶)環境、不同的運行平臺都有可能需要不同配置或資源的情況。假如各個環境下的差別很小的話,我們可以在項目編譯之后手工修改或者寫個 shell script 自動修改,但如果需要修改的項目很多而且復雜的話,則應該使用?Apache Maven?的 Profile 和 Filtering 功能來解決。(當然前提是你的項目必須是用 Maven 構建的啦,哈哈,還有測試階段所使用到的資源文件實際上 Maven 默認已經劃分出來,所以并不需要本文所說的方法)
Filtering 功能
Filtering 是?Maven Resources Plugin 的一個功能,它會使用系統屬性或者項目屬性的值替換資源文件(*.properties,*.xml)當中 ${…} 符號的值。比如你系統屬性有一項 “user.name=foobar”,那么資源文件當中的 ${user.name} 符號會在 Maven 編譯時自動被替換為 “foobar”。
舉個例子:
默認的項目資源文件位于 “src/main/resources” 目錄,在該目錄下創建一個文件 “test.properties”,里面寫上一行:
Hello ${user.name}
然后修改項目文件(pom.xml)啟用 filtering 功能,如:
| <project>...<build>...<resources><resource><directory>src/main/resources</directory><filtering>true</filtering></resource>...</resources>...</build>... </project> |
然后編譯項目:
| $mvn clean compile -Duser.name=foobar |
查看輸出文件?target/classes/test.properties 的內容,可見原先的 “Hello {user.name}” 已經變成 “Hello foobar”。
我們也可以把 filtering 用到的變量寫在項目屬性段里,比如:
| <project>...<properties><user.name>foobar</user.name><user.email>foobar@some.com</user.email></properties>... </project> |
如果屬性項比較多的話,最佳實踐是把他們抽離出來獨立一個屬性文件,比如在你項目目錄(即 pom.xml 文件所在的目錄)新建一個屬性文件 project.properties:
| user.name=foobar user.email=foobar@some.com |
然后在 build/filters/filter 里指明使用這個屬性文件作為 filtering 屬性值的來源:
| <project>...<build>...<filters><filter>project.properties</filter></filters>...</build>... </project> |
Profile 功能
Profile 的作用是允許你在項目文件(pom.xml)里定義若干個 profile 段,然后在編譯時選擇其中的一個用于覆蓋項目文件原先的定義。接著上一個例子,如果我們需要為開發環境和生產環境定義不同的 user.name 屬性值,則我們在項目目錄里創建兩個屬性文件:
profile-development.properties,內容
| user.name=foobar |
profile-production.properties,內容
| user.name=tom |
然后在項目文件(pom.xml)里增加 profile 段,如下:
| <project>...<profiles><profile><id>development</id><activation><activeByDefault>true</activeByDefault></activation><build><filters><filter>profile-development.properties</filter></filters></build></profile><profile><id>production</id><build><filters><filter>profile-production.properties</filter></filters></build></profile></profiles> </project> |
在編譯項目時,可以使用 -P 參數指定需要使用的 profile 的 id,比如下面命令將會使用 development profile:
| $mvn clean compile -Pdevelopment |
如果想使用?production profile 則執行如下命令:
| $mvn clean compile -Pproduction |
假如不指定 -P 參數的話,則會使用 activeByDefault=true 的一項(即 development)。
至此,通過 filtering 和 profile 功能實現了為開發環境和生產環境使用不同配置值的目的。當然 profile 還可以允許你添加更多的定義,比如為某一個 profile 添加不同的資源文件。在一些大中型項目里,不同的環境可能僅僅修改配置值并不足夠,可能還需要某個配置文件整個替換,那么就應該在 profiles/profile/build/resources 段里指定了。詳細的可以參閱附錄鏈接。
附錄:
- Maven Resources plugin – Filtering
- Maven: The Complete Reference – Build Profiles
================================
http://piotrnowicki.com/2012/10/filtered-resources-in-maven/
Piotr Nowicki
AboutFiltered Resources in Maven
Maven has some really great features. One of them is filtered resources.
Basically, if you use Maven for some time, I’m sure you know what by default everything you put in src/main/resources will be added to the classpath in the resulting artifact (e.g. in the WEB-INF/classes for a *.war archive.) Putting resources in this location is a common way of adding Java properties file to your project.
Now what is interesting: you can use Maven variables in those resource files and they can be swapped into final value during the process-resource phase. You just need to tell Maven that it is not a “regular” resource and that it should be filtered.
As an example: assume you have a following properties file:
src/main/resources/application.properties
app.version = ${version}And you add the following section to your pom.xml file:
pom.xml
<project><build>...<resources><resource><directory>src/main/resources</directory><includes><include>application.properties</include></includes><filtering>true</filtering></resource></resources></build> <project>During the prepare-resources phase the application.properties file will be filtered by Maven. The ${...} placeholders will be filled with proper values and the resulting application.properties will be produced and placed somewhere in the target directory. Its content will be something like:
app.version = 0.1.1-SNAPSHOTYou can use variables available out-of-the-box in Maven or some additional ones coming e.g. from the Maven plugins or your own defined in the <properties> pom.xml element. It’s pretty neat if you combine it with Maven Build Number plugin which can add your revision or some custom made build number and save it to your runtime accessible property file.
As a side note, if you define the exact files / directories you want to be filtered and want to treat the rest of the files as regular ones (not filtered) you should instruct Maven to do so. It seems that if you define at least one <resource> element, the default values doesn’t apply anymore. Something like this should do the work:
<project><build>...<resources><resource><directory>src/main/resources</directory><includes><include>application.properties</include></includes><filtering>true</filtering></resource><resource><directory>src/main/resources</directory></resource></resources></build> <project>You can see an example of how I used it with Build Number plugin here.
總結
以上是生活随笔為你收集整理的Apache Maven 使用 profile 和 filtering 实现多种环境下的资源配置管理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CSS的几个属性display,floa
- 下一篇: org.eclipse.jdt.inte