首先简单介绍下 Maven 的 profile 是什么。对于人来说,profile 是指人的肖像,轮廓,比如论坛里每个人注册了帐号后,可以设置自己的 profile,放上照片,介绍等等。对于 Maven 来说又是怎样呢?整个项目定义好了项目对象模型(POM),就像论坛为每个人提供了默认的行为功能,如果我想改变我机器上的 POM 呢?这时就可以使用 profile。下面举个例子:
1. <profiles>
2. <profile>
3. <id>jdk16</id>
4. <activation>
5. <jdk>1.6</jdk>
6. </activation>
7. <modules>
8. <module>simple-script</module>
9. </modules>
10. </profile>
11. </profiles>
这个 profile 的意思是,当机器上的 JDK 为1.6的时候,构建 simple-script 这个子模块,如果是1.5或者1.4,那就不构建,这个 profile 是由环境自动激活的。
我们需要在合适的地方使用合适的 profile ,并且在合适的时候用合适的方式将其激活,你不能在构建服务器上激活非公共的 profile,你也不能要求开发人员写很复杂的命令来使用常规的 profile。因此这里介绍一下几种 profile 的激活方式。
1. 根据环境自动激活。
如前一个例子,当 JDK 为1.6的时候,Maven 就会自动构建 simple-script 模块。除了 JDK 之外,我们还可以根据操作系统参数和 Maven 属性等来自动激活 profile,如:
1. <profile>
2. <id>dev</id>
3. <activation>
4. <activeByDefault>false</activeByDefault>
5. <jdk>1.5</jdk>
6. <os>
7. <name>Windows XP</name>
8. <family>Windows</family>
9. <arch>x86</arch>
10. <version>5.1.2600</version>
11. </os>
12. <property>
13. <name>mavenVersion</name>
14. <value>2.0.5</value>
15. </property>
16. <file>
17. <exists>file2.properties</exists>
18. <missing>file1.properties</missing>
19. </file>
20. </activation>
21. ...
22. </profile>
2. 通过命令行参数激活。
这是最直接和最简单的方式,比如你定义了一个名为 myProfile 的 profile,你只需要在命令行输入 mvn clean install -Pmyprofile 就能将其激活,这种方式的好处很明显,但是有一个很大的弊端,当 profile 比较多的时候,在命令行输入这写 -P 参数会让人觉得厌烦,所以,如果你一直用这种方式,觉得厌烦了,可以考虑使用其它自动激活的方式。
3. 配置默认自动激活。
方法很简单,在配置 profile 的时候加上一条属性就可以了,如:
1. <profile>
2. <id>dev</id>
3. <activation>
4. <activeByDefault>true</activeByDefault>
5. </activation>
6. ...
7. </profile>
在一个特殊的环境下,配置默认自动激活的 profile 覆盖默认的 POM 配置,非常简单有效。
4. 配置 settings.xml 文件 profile 激活。
settings.xml 文件可以在 ~/.m2 目录下,为某个用户的自定义行为服务,也可以在 M2_HOME/conf 目录下,为整台机器的所有用户服务。而前者的配置会覆盖后者。同理,由 settings.xml 激活的 profile 意在为用户或者整个机器提供特定环境配置,比如,你可以在某台机器上配置一个指向本地数据库 URL 的 profile,然后使用该机器的 settings.xml 激活它。激活方式如下:
1. <settings>
2. ...
3. <activeProfiles>
4. <activeProfile>local_db</activeProfile>
5. </activeProfiles>
6. </settings>
Maven 提供的 profile 功能非常强大和灵活,用得好的话,可以有效的隔离很多特殊的配置,使得整个项目能在不同环境中顺利的构建。但是,强大和灵活带来得问题是相对难掌握,希望本文能对 Maven 使用者有帮助。
============================分隔线===========================
4.2 profile的定义位置
对于使用Maven3,我们可以有多个地方定义profile。定义的地方不同,它的作用范围也不同。
(1) 针对于特定项目的profile配置我们可以定义在该项目的pom.xml中。
(2) 针对于特定用户的profile配置,我们可以在用户的settings.xml文件中定义profile。该文件在用户家目录下的“.m2”目录下。
(3) 全局的profile配置。全局的profile是定义在Maven安装目录下的“conf/settings.xml”文件中的。
4.3 profile中能定义的信息
profile中能够定义的配置信息跟profile所处的位置是相关的。以下就分两种情况来讨论,一种是定义在settings.xml中,另一种是定义在pom.xml中。
4.3.1 profile定义在settings.xml中
当profile定义在settings.xml中时意味着该profile是全局的,它会对所有项目或者某一用户的所有项目都产生作用。因为它是全局的,所以在settings.xml中只能定义一些相对而言范围宽泛一点的配置信息,比如远程仓库等。而一些比较细致一点的需要根据项目的不同来定义的就需要定义在项目的pom.xml中。具体而言,能够定义在settings.xml中的信息有<repositories>、<pluginRepositories>和<properties>。定义在<properties>里面的键值对可以在pom.xml中使用。
4.3.2 profile定义在pom.xml中
定义在pom.xml中的profile可以定义更多的信息。主要有以下这些:
l <repositories>
l <pluginRepositories>
l <dependencies>
l <plugins>
l <properties>
l <dependencyManagement>
l <distributionManagement>
l 还有build元素下面的子元素,主要包括:
<defaultGoal>
<resources>
<testResources>
<finalName>
4.4 profile的激活方式
Maven给我们提供了多种不同的profile激活方式。比如我们可以使用-P参数显示的激活一个profile,也可以根据环境条件的设置让它自动激活等。下面将对它们一一进行介绍:
4.4.1 使用activeByDefault设置激活
先看下面一个配置
1. <profiles>
2. <profile>
3. <id>profileTest1</id>
4. <properties>
5. <hello>world</hello>
6. </properties>
7. <activation>
8. <activeByDefault>true</activeByDefault>
9. </activation>
10. </profile>
11.
12. <profile>
13. <id>profileTest2</id>
14. <properties>
15. <hello>andy</hello>
16. </properties>
17. </profile>
18. </profiles>
我们可以在profile中的activation元素中指定激活条件,当没有指定条件,然后指定activeByDefault为true的时候就表示当没有指定其他profile为激活状态时,该profile就默认会被激活。所以当我们调用mvn package的时候上面的profileTest1将会被激活,但是当我们使用mvn package –P profileTest2的时候将激活profileTest2,而这个时候profileTest1将不会被激活。
4.4.2 在settings.xml中使用activeProfiles指定处于激活状态的profile
我们可以在settings.xml中使用activeProfiles来指定需要激活的profile,这种方式激活的profile将所有情况下都处于激活状态。比如现在我们定义了如下两个profile
1. <profiles>
2. <profile>
3. <id>profileTest1</id>
4. <properties>
5. <hello>world</hello>
6. </properties>
7. </profile>
8.
9. <profile>
10. <id>profileTest2</id>
11. <properties>
12. <hello>andy</hello>
13. </properties>
14. </profile>
15. </profiles>
这里的profile可以是定义在settings.xml中的,也可以是定义在pom.xml中的。这个时候如果我们需要指定profileTest1为激活状态,那么我们就可以在settings.xml中定义activeProfiles,具体定义如下:
1. <activeProfiles>
2. <activeProfile>profileTest1</activeProfile>
3. </activeProfiles>
考虑这样一种情况,我们在activeProfiles下同时定义了多个需要激活的profile。这里还拿上面的profile定义来举例,我们定义了同时激活profileTest1和profileTest2。
1. <activeProfiles>
2. <activeProfile>profileTest1</activeProfile>
3. <activeProfile>profileTest2</activeProfile>
4. </activeProfiles>
从profileTest1和profileTest2我们可以看出它们共同定义了属性hello。那么这个时候我在pom.xml中使用属性hello的时候,它到底取的哪个值呢?是根据activeProfile定义的顺序,后面的覆盖前面的吗?根据我的测试,答案是非也,它是根据profile定义的先后顺序来进行覆盖取值的,然后后面定义的会覆盖前面定义的。
4.4.3 使用-P参数显示的激活一个profile
假设我们现在有如下定义的profiles
1. <profiles>
2. <profile>
3. <id>profileTest1</id>
4. <properties>
5. <hello>world</hello>
6. </properties>
7. </profile>
8. <profile>
9. <id>profileTest2</id>
10. <properties>
11. <hello>andy</hello>
12. </properties>
13. </profile>
14. <profiles>
那么当我们在进行Maven操作时就可以使用-P参数显示的指定当前激活的是哪一个profile了。比如我们需要在对项目进行打包的时候使用id为profileTest1的profile,我们就可以这样做:
1. mvn package –P profileTest1
当我们使用activeByDefault或settings.xml中定义了处于激活的profile,但是当我们在进行某些操作的时候又不想它处于激活状态,这个时候我们可以这样做:
1. Mvn package –P !profileTest1
这里假设profileTest1是在settings.xml中使用activeProfile标记的处于激活状态的profile,那么当我们使用“-P !profile”的时候就表示在当前操作中该profile将不处于激活状态。
4.4.4根据环境来激活profile
profile一个非常重要的特性就是它可以根据不同的环境来激活,比如说根据操作系统的不同激活不同的profile,也可以根据jdk版本的不同激活不同的profile,等等。
4.4.4.1根据jdk来激活profile
1. <profiles>
2. <profile>
3. <id>profileTest1</id>
4. <jdk>1.5</jdk>
5. </profile>
6. <profiles>
上面情况表示在jdk为1.5版本系列的时候激活profileTest1。
1. <profiles>
2. <profile>
3. <id>profileTest1</id>
4. <jdk>[1.4,1.7)</jdk>
5. </profile>
6. <profiles>
上面的情况表示在jdk为1.4、1.5和1.6的时候激活profileTest1。
4.4.4.2根据操作系统来激活profile
1. <profiles>
2. <profile>
3. <id>profileTest1</id>
4. <activation>
5. <os>
6. <name>Windows XP</name>
7. <family>Windows</family>
8. <arch>x86</arch>
9. <version>5.1.2600</version>
10. </os>
11. </activation>
12. </profile>
13. </profiles>
上面的情况就是根据操作系统的类型来激活profileTest1。
4.4.4.3根据系统属性来激活profile
1. <profiles>
2. <profile>
3. <id>profileTest1</id>
4. <activation>
5. <property>
6. <name>hello</name>
7. <value>world</value>
8. </property>
9. </activation>
10. </profile>
11. </profiles>
上面的profileTest1将在提供了系统属性hello,并且其值为world的时候激活。下面的做法可以激活profileTest1。
1. mvn package –Dhello=world
当是下面的这种定义形式时,profileTest1将在指定了系统属性hello,且其值为任意值的时候被激活。
1. <profiles>
2. <profile>
3. <id>profileTest1</id>
4. <activation>
5. <property>
6. <name>hello</name>
7. </property>
8. </activation>
9. </profile>
10. </profiles>
4.4.4.4根据文件是否存在激活profile
1. <profiles>
2. <profile>
3. <id>profileTest1</id>
4. <activation>
5. <file>
6. <exists>target</exists>
7. </file>
8. </activation>
9. </profile>
10. </profiles>
上面的定义表示当存在target文件时激活profileTest1。
1. <profiles>
2. <profile>
3. <id>profileTest1</id>
4. <activation>
5. <file>
6. <missing>target</missing>
7. </file>
8. </activation>
9. </profile>
10. </profiles>
上面的定义表示当不存在target文件时激活profileTest1。
4.5 查看当前处于激活状态的profile
我们可以同时定义多个profile,那么在建立项目的过程中,到底激活的是哪一个profile呢?Maven为我们提供了一个指令可以查看当前处于激活状态的profile都有哪些,这个指定就是mvn help:active-profiles。
现在假设我们的settings.xml文件中有如下profile的定义:
1. <profiles>
2. <profile>
3. <id>profileTest1</id>
4. <activation>
5. <file>
6. <missing>target</missing>
7. </file>
8. </activation>
9. </profile>
10. </profiles>
11.
12. <activeProfiles>
13. <activeProfile>profileTest1</activeProfile>
14. </activeProfiles>
这个时候我们可以看到,我们已经定义了profileTest1始终为激活状态,这个时候我们使用mvn help:active-profiles查看处于激活状态的profile时,就会打印出如下内容: