一个优秀的构建系统必须足够灵活,它应该能让项目在不同的环境下都能成功地构建。Maven为了支持构建的灵活性,内置了三大特性,即属性、Profile和资源过滤。这里我们只介绍Profile的使用,以及和Spring Profile的整合。
1、Maven Profile
典型的项目一般都会有开发环境、测试环境以及生产环境,在不同的环境中,项目的源码应该使用不同的方式进行构建,这就要求项目构建的时候需要识别所在环境并使用正确的配置。为了能让构建在各个环境下方便的移植,Maven引入了profile的概念,profile可以让我们定义一系列的配置信息,然后指定其激活条件。这样我们就可以定义多个profile,然后每个profile对应不同的激活条件和配置信息,从而达到不同环境使用不同配置信息的效果。
1.1 profile的种类
根据具体需要,可以在以下位置声明profile:
- pom.xml: 很显然,pom.xml中声明的profile只对当前项目有效。
- 用户settings.xml: 用户目录下 .m2/settings.xml中的profile对本机上该用户所有的Maven项目有效。
- 全局settings.xml: Maven安装目录下conf/setting.xml中的profile对本机中上所有的Maven项目有效。
- profiles.xml(Maven2): 还可以在项目根目录下使用一个额外的profiles.xml文件来声明profile,不过该特性已经在Maven3中被移除。建议用户将这类profile移到settings.xml中。
使用最多的两种方式是用户settings.xml和pom.xml方式,下面简要说明下不同位置的profile可使用的元素种类:
POM中的profile可使用的元素,
<project>
<repositories></repositories>
<pluginRepositories></pluginRepositories>
<distributionManagement></distributionManagement>
<dependencies></dependencies>
<dependencyManagement></dependencyManagement>
<modules></modules>
<properties></properties>
<reporting></reporting>
<build>
<plugins></plugins>
<defaultGoal></defaultGoal>
<resources></resources>
<testResources></testResources>
<finalName></finalName>
</build>
</project>
POM外部的profile可使用元素,
<project>
<repositories></repositories>
<pluginRepositories></pluginRepositories>
<properties></properties>
</project>
1.2 激活方式
1.2.1 默认激活方式
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
...
</profile>
</profiles>
如果POM中任何一个profile通过其他方式激活诶激活了,这个默认配置就会失效。
1.2.2 命令行激活
可以使用mvn命令行参数-P加上profile的id来激活profile,多个id之间以逗号分隔。
$mvn clean install -Pdev
1.2.3 settings文件显示激活
如果希望某个profile一直处于激活状态,就可以配置settings.xml文件的activeProfiles元素。
<settings>
...
<activeProfiles>
<actvieProfile>dev</activeProfile>
</activeProfiles>
...
</settings>
1.2.4 系统属性激活
用户可以配置当某系统属性存在的时候,自动激活profile。然后在命令行声明系统属性:$mvn clean install -Dtest
,这种方式和第2种很像,而且多个profile可以使用同一个系统属性来激活。
<profiles>
<profile>
<activation>
<property>
<name>test</name>
</property>
</activation>
...
</profile>
</profiles>
1.2.5 操作系统环境激活
Profile可以自动根据操作系统环境激活。这里的family的值包括Windows、UNIX和Mac等,而其他几项name、arch、version,用户可以通过查看环境中的系统属性os.name、os.arch、os.version获得。
<profiles>
<proflie>
<activation>
<os>
<name>Windows XP</name>
<family>Windows</family>
<arch>x86</arch>
<version>5.1.2600</version>
</os>
...
</activation>
</profile>
</profiles>
1.2.6 文件存在与否激活
Maven能够根据项目中某个文件存在与否来决定是否激活profile.
<profiles>
<profile>
<activation>
<file>
<missing>x.properties</missing>
<exists>y.properties</exists>
</file>
</activation>
...
</profile>
</profiles>
1.3 示例
在开发的过程中,我们一般会正在src/main/resource目录下放置配置文件xxx.xml或者xxx.properties。下面以数据库的配置为例来说明profile的使用方式,假设配置文件中有如下数据库配置:
database.jdbc.driverclass=com.mysql.jdbc.Driver
database.jdbc.connectionURL=jdbc:mysql://localhost:3306/test
database.jdbc.username=dev
database.jdbc.passowrd=dev-pwd
如果只是在一个环境中使用就没有什么问题,但是当测试人员想要构建项目进行测试,或者部署上线到生产环境,往往这些环境的信息是不同的,这就需要修改这个配置文件了。将这些配置参数提取到profile中:
database.jdbc.driverclass=${db.driver}
database.jdbc.connectionURL=${db.url}
database.jdbc.username=${db.username}
database.jdbc.passowrd=${db.password}
pom.xml文件中新增prfile:
<profiles>
<profile>
<id>dev</id>
<properties>
<db.driver>com.mysql.jdbc.Driver</db.driver>
<db.url>jdbc:mysql://localhost:3306/test</db.url>
<db.username>dev</db.username>
<db.password>dev-pwd</db.password>
</properties>
</profile>
<profile>
<id>deploy</id>
<properties>
<db.driver>com.mysql.jdbc.Driver</db.driver>
<db.url>jdbc:mysql://localhost:3306/deploy</db.url>
<db.username>deploy</db.username>
<db.password>deploy-pwd</db.password>
</properties>
</profile>
</profiles>
有了属性定义,配置文件中也有了这些属性。但是Maven属性默认只有在POM中才会被解析,放在src/main/resources/
下并不会被解析。因此需要借助maven-resource-plugin
插件来为资源目录开启过滤,这样Maven就能解析资源文件中的Maven属性了。
<resources>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
<filtering>true</filtering>
</resource>
<resource>
<directory>${project.basedir}/src/test/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
Maven允许用户声明多个资源目录,并且为每个资源目录提供不同的过滤配置。最后,只需要在命令行激活profile,Maven就能够在构建项目的的时候使用profile中属性值替换数据库配置文件中的属性引用。运行命令行如下:
$mvn clean install -Pdev
2、Spring Profile
Spring profile是Spring 3.1引入的概念,通过定义profile
来将若干不同的bean
定义组织起来,从而实现不同环境自动激活不同的profile
来切换配置参数的功能。
在实际项目的开发过程中,开发环境一般使用项目中自带文件,而在部署生产环境的时候使用指定目录下的配置文件,下面就以配置文件切换为例来说明profile的使用方法:
2.1 在applicationContext.xml里定义profile
<!-- dev环境 -->
<beans profile="dev">
<context:property-placeholder ignore-resource-not-found="true" location="classpath:config/xxxx.properties" />
....
</beans>
<!-- deploy环境 -->
<beans profile="deploy">
<context:property-placeholder ignore-resource-not-found="true" location="file:D:\xx\xxx\xxxx.properties"/>
....
</beans>
或者:
<context:property-placeholder system-properties-mode="OVERRIDE" file-encoding="UTF-8" properties-ref="configProperties" />
<beans profile="dev">
<bean id="configProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>classpath:config/xxxx.properties</value>
</list>
</property>
</bean>
</beans>
<beans profile="deploy">
<bean id="configProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>file:D:\xx\xxx\xxxx.properties</value>
</list>
</property>
</bean>
</beans>
2.2 在web.xml定义默认profile
默认profile
是指在没有任何profile
被激活的情况下,默认profile
内定义的内容将被使用。
<context-param>
<param-name>spring.profiles.default</param-name>
<param-value>dev</param-value>
</context-param>
2.3 激活profile
spring为我们提供了大量的激活profile
的方法,可以通过代码来激活,也可以通过系统环境变量、JVM参数、servlet上下文参数来定义spring.profiles.active
参数激活profile
,这里我们通过定义servlet上下文参数参数实现。
<context-param>
<param-name>spring.profiles.active</param-name>
<param-value>${profiles.activation}</param-value>
</context-param>
其中,${profiles.activation}
需要在实际运行项目的时候指定环境变量,这样既可以做到不同的环境下切换不同的配置文件,也可以直接设置具体值,这样可以省去2.4节的环境属性设置。
2.4 运行项目
这里以jetty服务器做介绍,如果使用maven内置jetty插件启动,我们需要在pom中定义环境属性,如下图:
如果是使用eclipse jetty插件启动,我们需要在服务器配置中增加环境变量,如下图:
3、Maven整合Spring profile
实际项目中我们大多以Maven来管理项目,所以这一部分来介绍如何在Maven中整合Spring profile。
1.3节的示例已经介绍了在maven的pom文件中如何增加profile,并且指定了默认的激活profile,现在我们将其改为
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<profiles.activation>dev</profiles.activation>
</properties>
</profile>
<profile>
<id>deploy</id>
<properties>
<profiles.activation>deploy</profiles.activation>
</properties>
</profile>
</profiles>
注意这里的<profiles.actviation>
属性名称要和2.3 激活profile里配置的属性值${profiles.activation}
对应,用于在打包的时候指定激活的profile
3.1 配置Maven插件,进行资源过滤
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<warName>${profiles.activation}</warName>
<!-- 激活spring profile -->
<webResources>
<resource>
<filtering>true</filtering>
<directory>${basedir}/src/main/webapp</directory>
<includes>
<include>**/web.xml</include>
</includes>
</resource>
</webResources>
<warSourceDirectory>${basedir}/src/main/webapp</warSourceDirectory>
<webXml>${basedir}/src/main/webapp/WEB-INF/web.xml</webXml>
<warName>实际打包名称或者用${profiles.activation}替代,否则会找不到war包</warName>
</configuration>
</plugin>
这一部很关键: 配置的目的是为了打包的时候,替换web.xml中配置的servlet上下文参数值${profiles.activation}
,如果不配置,会发现打包后的web.xml中${profiles.activation}
并没有被替换。
3.2 打包
打包到部署环境
$mvn clean install -Pdeploy
打包到体验环境
$mvn clean install -Pdev
参考书籍:
1. Maven实战 许晓斌著
2. spring proflie参考网上资料以及实际使用