##背景
在日常的项目开发过程中, 会有很多的配置文件, 而项目对应有多套环境(开发、测试、预发布、生产), 不同的环境使用的配置属性又不一样, 比如数据库连接属性、服务器日志文件路径、缓存服务器地址等等, 如果我们每次打包部署到不同的环境都要频繁的修改配置文件的话, 非常的麻烦, 而且势必会增加一定的风险。那么如何解决这个问题呢?
##解决方案 使用 Maven 的 filtering 和 profile 功能, 我们只需要在 pom 文件中做一些简单的配置就可以隔离不同环境的配置文件, 非常方便。
##实现原理 ###filtering 主要用来替换项目中资源文件(.xml、.properties)当中由 ${...} 标记的变量, 比如 ${zk.hosts}。如果在配置配置文件中配置了 zk.hosts=a.b.c.d 的话, 那么使用 Maven 编译项目的时候, 会自动的把 ${zk.hosts} 替换为 a.b.c.d。 ###代码示例 新建一个用于测试的 Maven 项目, POM 文件内容如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.jackiehff.codeproject</groupId>
<artifactId>maven-sample</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>maven-sample</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
</project>
在 src/main/resources 目录下新建一个 config.properties 文件, 文件内容如下:
Hello ${your.name}!
####使用-D选项 在命令行编译时, 可以使用 -D 选项指定变量的值, 如下:
mvn resources:resources -Dyour.name="world"
执行完之后 target/classes/config.properties 中文件内容为:
Hello world!
可以看到 your.name 变量的值变成了 world。 ####使用预定义项目属性 还可以在 POM 文件中的 <properties> 元素下指定自定义变量和它们的值。比如可以在 <properties> 元素下新增一个 <your.name> 元素, 并指定 <your.name> 元素的值。
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<your.name>world</your.name>
</properties>
执行 mvn resources:resources 命令, 可以发现 target/classes/config.properties 中文件内容也变成了:
Hello world!
####使用属性文件 可以把属性配置放置在一个单独的 .properties 文件中。例如我们在 src/main/resources 目录下面创建一个 test.properties, 内容如下:
your.name=world
接着需要在配置文件中指定 test.properties 的路径, 如下:
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<filters>
<filter>src/main/resources/test.properties</filter>
</filters>
</build>
执行 mvn resources:resources 命令, 可以发现 target/classes/config.properties 中文件内容也变成了:
Hello world!
###profile Maven profile 可以使用操作系统信息、jdk信息以及属性值等作为依据, 来激活相应的 profile。比如需要为开发环境和生产环境定义不同的 your.name 属性值, 我们在 src/main/resources 目录下创建两个属性文件 config-dev.properties 和 config-online.properties。
config-dev.properties 文件内容如下:
your.name=dev
config-online.properties 文件内容如下:
your.name=online
接着修改 POM 文件如下:
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<filters>
<filter>src/main/resources/config-${env}.properties</filter>
</filters>
</build>
<profiles>
<profile>
<id>dev</id>
<properties>
<env>dev</env>
</properties>
<activation>
<!-- 默认激活开发环境配制,使用config-dev.properties来替换 config.properties 文件中的 ${your.name} -->
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>online</id>
<properties>
<env>online</env>
</properties>
</profile>
</profiles>
执行 mvn clean compile 命令, 可以看到 target/classes/config.properties 中文件内容变成了:
Hello dev!
在命令行编译项目时, 也可以使用 -P 参数指定需要激活的 profile 的 id, 比如下面命令将会激活 id 为 dev 的 profile:
mvn clean compile -Pdev
如果想激活 id 为 online 的 profile, 只需要做如下修改:
mvn clean compile -Ponline
假如不指定 -P 参数的话,则会使用 activeByDefault=true 的 profile。
##参考资料 http://maven.apache.org/guides/introduction/introduction-to-profiles.html https://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html