构建项目时可能会遇到在测试(如单元测试)、开发、模拟、生产等不一样环境下须要不一样配置(properties、xml)或资源(jpg、png、mp3)的状况。好比常见的数据库链接(即 jdbc url)的值,在不一样的环境下可能有以下几种值:html
或者一样是生产环境,针对(产品)交付给A公司客户的与交付给B公司客户的须要不一样配置或者资源,好比产品界面中的公司名称、公司LOGO等。mysql
又或者针对不一样的操做系统(如 Windows,Linux)须要为某个配置设定不一样的文件路径。sql
可见,在不一样的软件开发生命周期阶段、不一样的最终客户(用户)环境、不一样的运行平台都有可能须要不一样配置或资源的状况。假如各个环境下的差异很小的话,咱们能够在项目编译以后手工修改或者写个 shell script 自动修改,但若是须要修改的项目不少并且复杂的话,则应该使用 Apache Maven 的 Profile 和 Filtering 功能来解决。(固然前提是你的项目必须是用 Maven 构建的啦,哈哈,还有测试阶段所使用到的资源文件实际上 Maven 默认已经划分出来,因此并不须要本文所说的方法)shell
Filtering 是 Maven Resources Plugin 的一个功能,它会使用系统属性或者项目属性的值替换资源文件(*.properties,*.xml)当中 ${…} 符号的值。好比你系统属性有一项 “user.name=foobar”,那么资源文件当中的 ${user.name} 符号会在 Maven 编译时自动被替换为 “foobar”。数据库
举个例子:apache
默认的项目资源文件位于 “src/main/resources” 目录,在该目录下建立一个文件 “test.properties”,里面写上一行:maven
Hello ${user.name}单元测试
而后修改项目文件(pom.xml)启用 filtering 功能,如:测试
<project> ... <build> ... <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> </resource> ... </resources> ... </build> ... </project>
而后编译项目:ui
$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 的做用是容许你在项目文件(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 段里指定了。详细的能够参阅附录连接。