本文是译文,原文链接 http://maven.apache.org/guides/introduction/introduction-to-profiles.html
Introduction to Build Profiles
Apache Maven 2.0 竭尽全力去保证构建是可移植的,这意味着允许构建配置在 POM 文件中,从而避免所有的文件系统引用。Maven 倾向于更重地依赖本地仓库来存储构建所需的元信息。
然而有时候可移植性不是完全可能的,比如下面这些情况:
- 插件可能会被配置一些本地路径;
- 一些依赖版本的变更也是不可避免的;
- 工程的 artifact 名字也可能会被调整;
- 你甚至可能需要在检测到某些特殊构建环境后需要包含整个构建插件。
为了实现上述效果,Maven 2.0 引入了 profile 概念。Profiles 可以指定使用 POM 中所有配置元素的一个子集,它们在构建时修改 POM,意在通过提供补充配置元素来实现针对不同环境提供不同的参数信息(比如在 debug、online 环境下链接不同的数据库);同样 profile 可以轻易地使团队不同成员构建出不同的结果。对 profiles 的适当使用可以你保证工程的可移植性,这会大大减少对 Maven -f 选项的使用(-f 选项可以指定从另外的地方加载 POM 文件)。
What are the different types of profiles? Where is each defined?
- Per Project
- 定义在 POM 文件里
- Per User
- 定义在 Maven-setting 里(%USER_HOME%/.m2/settings.xml)
- Gloabal
- 定义在全局 Maven-setting 里(%M2_HOME%/conf/settings.xml)
- Profile descriptor
- 在工程根目录下的一个本地配置文件(profiles.xml)
How can a profile be triggered? How does this vary according to the type of profile being used?
一个 profile 可以通过下面几种方式触发:
- 显式触发
- 通过 Maven 设置
- 基于环境变量
- 在于操作系统
- 某个文件是否存在
Details on profile activation
显式触发是指通过命令行的 -P 选择指定 profile。这个选项可以指定使用多个 profile,各个 profile 之间用逗号分隔。启动了这个构建参数后,指定的 profile 连同默激活(通过在<activeProfiles>区中配置的 profile)的 profile 共同生效。
mvn groupId:artifactId:goal -P profile-1,profile-2Profiles 可以通过 Maven 的配置激活,具体是在 <activeProfiles> 里面配置,具体示例如下:
<settings> ... <activeProfiles> <activeProfile>profile-1</activeProfile> </activeProfiles> ... </settings>上述配置中的 profiles 每次构建的时候都会默认激活。
Profiles 可以通过检测构建环境来自动触发。这个触发器是通过在 profile 中配置 <activation> 来实现的。当前这种机制仅支持根据前缀来匹配 JDK 版本,JDK 版本信息是通过在 system property 中获取得到的。下面这个配置会在 JDK 版本以 '1.4' 开头的环境中触发:
<profiles> <profile> <activation> <jdk>1.4</jdk> </activation> ... </profile> </profiles>
当然也可以制定符合条件的 JDK 范围,下面的例子声明了在1.3、1.4、1.5 版本中触发:
<profiles> <profile> <activation> <jdk>[1.3,1.6)</jdk> </activation> ... </profile> </profiles>
下面是一个通过操作系统版本设置触发 profile 的例子,更多的操作系统值参考这个文档。
<profiles> <profile> <activation> <os> <name>Windows XP</name> <family>Windows</family> <arch>x86</arch> <version>5.1.2600</version> </os> </activation> ... </profile> </profiles>下面这个 profile 在系统属性(system property)中存在 'debug' 属性的情况下会触发:
<profiles> <profile> <activation> <property> <name>debug</name> </property> </activation> ... </profile> </profiles>下面这个 profile 在系统属性中 'environment' 的值指定为 'test' 的情况下会触发:
<profiles> <profile> <activation> <property> <name>environment</name> <value>test</value> </property> </activation> ... </profile> </profiles>激活上述的 profile ,可以通过下面这个命令行来实现
mvn groupId:artifactId:goal -Denvironment=test从 Maven 3.0 起, profile 也可以通过 settings.xml 中被激活的 profile 的属性来激活。
Note:环境变量会被正则化,比如 Foo 会被正则成为 env.Foo , 另外在 windows 中环境变量统一会被正则成全大写的形式。
下面这个 profile 会在 target/generated-sources/axistools/wsdl2java/org/apache/maven 这个文件丢失的时候触发。
<profiles> <profile> <activation> <file> <missing>target/generated-sources/axistools/wsdl2java/org/apache/maven</missing> </file> </activation> ... </profile> </profiles>从 maven 2.0.9 起 <exists> 和 <missing> 标签可以被篡改,支持系统属性(${user.home})或环境变量(${env.HOME})作为变量。注意在 POM 本身中定义的属性值是不能当做篡改变量用的。
Profiles 也可以通过配置 <activeByDefault> 激活,如下面的示例:
<profiles> <profile> <id>profile-1</id> <activation> <activeByDefault>true</activeByDefault> </activation> ... </profile> </profiles>在所有构建中这个 profile 会被默认激活,除非同一个 POM 文件中另一个 profile 被激活。如果某个 profile 被通过命令行或者 activation 配置激活,那么所有通过<activeByDefault>设置的 profile 都不会被激活。
Deactivating a profile
从 Maven 2.0.10 起,可以禁默一个或多个 profiles,方法是在命令行中在这些 profile id 前面加一个 '!' 或者 '-',如下例所示:
mvn groupId:artifactId:goal -P !profile-1,!profile-2这个可以禁默通过 activeByDefault 设置激活的profile,也可以禁默被 activation 配置激活的 profile。
Which areas of a POM can be customized by each type of profile? Why?
我们在这里再讨论一下 profile 可以用来指定什么东西,这个问题像 profile 配置的其他方面一下,答案不是很直观。
根据你选择在哪里配置你的 profile,你将会接触到各种 POM 配置选项。
- Profiles in external files
在外部文件(比如在 settings.xml 或者 profiles.xml)中指定的 profile 在严格意义上说是不可移植的。任何看起来很大可能性改变构建结果的配置都应该严格放在 POM 文件里。像一些仓库列表这样的信息可以放到外部文件中。因此你仅能修改<repositories> 和 <pluginRepositories> 这样的配置,再加上额外的 <properties> 配置。
<properties> 配置允许你以 key-value 的形式指定哪些信息在处理 POM 的时候会被篡改。这使你可以通过 ${profile.provided.path} 的方式指定一个插件的配置。
- Profiles in POMs
另一方面,如果你的 profiles 可以合理地在 POM 中指定,那你的选择余地就大的多。权衡的标准是你可以仅仅修改对应的工程和它的子模块。这些 profiles 是内联指定的,所以能更好地保证程序的可移植性,因为其他人可以毫无风险地应用你的修改。
在 POM 文件里的 profile 可以修改 POM 的下列元素:
- <repositories>
- <pluginRepositories>
- <dependencies>
- <plugins>
- <properties>
- <modules>
- <reporting>
- <dependencyManagement>
- <distributionManagement>
<build> 下面的元素,主要是:
- <defaultGoal>
- <resources>
- <testResources>
- <finalName>
Profile Pitfalls
我们前面已经提到了添加 profile 到你的构建中有可能破坏工程的可移植性,那么我们就尽可能多地强调一下哪些环境中对 profile 的使用会导致工程不可移植的问题。
在使用 profile 的时候,两个主要的问题要牢记于心:一个是外部属性(通常用在插件配置中);另一个是 profile 自然集的不完全指定。
External Properties
外部属性定义是指在 pom.xml 之外定义但没有在 pom.mxl 内部对应的 profile 中定义的属性值。这种情况多发生在插件配置中。举个例子,在 settings.xml 中的某个 profile 中指定 appserver 路径,可能引起你的集成测试插件在团队中其他成员没有相同 settings.xml 配置的情况下构建失败。考虑到一个 web 应用工程的 pom 片段如下:
<project> ... <build> <plugins> <plugin> <groupId>org.myco.plugins</groupId> <artifactId>spiffy-integrationTest-plugin</artifactId> <version>1.0</version> <configuration> <appserverHome>${appserver.home}</appserverHome> </configuration> </plugin> ... </plugins> </build> ... </project>然后你再本地 的 ~/.m2/settings.xml 中有如下配置片段:
<settings> ... <profiles> <profile> <id>appserverConfig</id> <properties> <appserver.home>/path/to/appserver</appserver.home> </properties> </profile> </profiles> <activeProfiles> <activeProfile>appserverConfig</activeProfile> </activeProfiles> ... </settings>当你构建 integration-test 的时候,你的集成测试通过,因为你提供给测试插件的路径是有效的。
但是当你的同事试图构建 integration-test 的时候缺发现构建失败,原因是无法解析 <appserverHome> 元素。
Incomplete Specification of a Natural Profile Set
除了上述问题外,经常出错的是在 profile 中没有覆盖到所有的情况。我们来看看下面这个 pom.xml 例子:
<project> ... <build> <plugins> <plugin> <groupId>org.myco.plugins</groupId> <artifactId>spiffy-integrationTest-plugin</artifactId> <version>1.0</version> <configuration> <appserverHome>${appserver.home}</appserverHome> </configuration> </plugin> ... </plugins> </build> ... </project>现在我们考虑下面这个在 pom.xml 中的 profile:
<project> ... <profiles> <profile> <id>appserverConfig-dev</id> <activation> <property> <name>env</name> <value>dev</value> </property> </activation> <properties> <appserver.home>/path/to/dev/appserver</appserver.home> </properties> </profile> <profile> <id>appserverConfig-dev-2</id> <activation> <property> <name>env</name> <value>dev-2</value> </property> </activation> <properties> <appserver.home>/path/to/another/dev/appserver2</appserver.home> </properties> </profile> </profiles> .. </project>这个 profile 看起来跟上面那个例子很像,只有一点不同:这里又配置了一个 appserverConfig-dev-2 这个profile,这个 profile 是通过 env=dev-2 来激活的。
这样,执行:
mvn -Denv=dev-2 integration-test可以构建成功,应用的属性是由 appserverConfig-dev-2 提供的。当我们执行:
mvn -Denv=dev integration-test也可以构建成功,应用的属性是由 appserverConfig-dev 提供的。但是当我们执行:
mvn -Denv=production integration-test将会构建失败。原因是上述两个 profile 中的任何一个都没有被激活,导致 appserverHome 这个参数找不到。
How can I tell which profiles are in effect during a build?
我们可以用 Maven Help Plugin 来确定构建期间那个 profile 在起作用。
mvn help:active-profiles这里我们一起来看几个例子,来更好地理解一下 active-profiles。在上面那个 profile 的配置情况下,输入下面的 maven 命令
mvn help:active-profiles -Denv=dev会得到这样的结果:
The following profiles are active: - appserverConfig-dev (source: pom)如果我们想看到具体是哪个 profile 的配置参数值最终被应用了,可以使用 effective-pom 这个目标,具体的命令如下:
mvn help:effective-pom -P appserverConfig-dev -Doutput=effective-pom.xml
Naming Conventions
现在我们知道了 profile 是解决多环境下构建差异化问题的很自然的解决方法。我们称 profile 中解决差异化问题的概念是'自然集',对这个集合的思考是非常重要的。
关于如何组织和管理自然集的变更是非常重要的。就像优秀的开发人员会写出自解释的代码一样,profile 的 id 也需要对他的意图有比较好的暗示。一个很好的实践是使用公共系统属性触发器作为 profile 名字的一部分。比如用 env-dev,env-test,env-prod 作为 profile 的名字,这些 profile 都是被 env 这个系统属性触发的。这样的系统在特殊环境的构建时具有很好的直觉暗示性。这样你要是想激活 env-test 可以输入下面这样的 maven 命令:
mvn -Denv=test <phase>
相关推荐
Maven是一个项目管理和构建自动化工具,主要服务于基于Java的软件项目。它是由Apache软件基金会提供的一个开源...6. **可移植性**:由于Maven使用POM文件来描述项目,因此项目配置可以在不同的机器和环境中轻松迁移。
在 POM 文件中,我们可以使用 `<profiles>` 元素来定义不同的 Profile。每个 Profile 都可以定义自己的配置文件,用于存储环境相关的配置信息。例如,我们可以定义一个开发环境的 Profile,如下所示: ```xml ...
下面将详细讲解如何使用Maven Profile实现多环境构建。 首先,让我们理解什么是Maven Profile。Maven Profile是Maven中的一种机制,允许开发者定义一组可选的配置,这些配置可以在特定条件下被激活。每个Profile...
它由Apache软件基金会提供支持,使用一种名为Project Object Model(POM)的XML文件来描述项目的构建过程、依赖关系和其他配置信息。 ### Maven的主要特点包括: 1. **依赖管理**:Maven能够自动处理项目所依赖的...
### Maven 使用文档详解 #### Maven 简介与特点 Maven 是一款强大的项目管理和构建工具,主要用于 Java 项目的管理。Maven 提供了统一的标准流程来管理项目的生命周期、依赖关系以及项目信息等,极大地提高了开发...
** Maven的使用示例 ** Maven是一款强大的Java项目管理工具,它可以帮助开发者构建、管理和部署项目。在Java开发环境中,Maven通过依赖管理和项目生命周期管理,极大地简化了项目的构建过程。下面我们将深入探讨...
**李兴华maven配置与使用** Maven是一款强大的项目管理工具,主要应用于Java开发领域。它通过统一的构建过程,简化了项目的构建、依赖管理和文档生成,使得开发者能够更专注于代码本身。以下是对Maven配置与使用的...
对于大型团队,可能还需要管理多个Maven项目,这时可以使用不同的用户配置,通过`<profiles>`和`<activeProfiles>`标签来切换不同环境的配置。 总的来说,Maven与开源中国Maven库的结合使用,对于国内Java开发者而...
【Maven简介与基本概念】 Maven是一个强大的项目管理和构建工具,主要应用于Java项目。它引入了项目对象模型...通过理解和熟练使用Maven,开发者可以更好地管理和维护复杂的项目结构,确保项目的可重复性和一致性。
在Maven的配置文件`settings.xml`中,`<mirrors>`和`<profiles>`元素用于设定仓库镜像和用户特定的配置,这些配置会影响Maven从哪里下载依赖。国内开发者经常因为网络原因,需要配置阿里云或清华大学的Maven镜像来...
5. **在Idea中使用profiles**:回到Idea,当你执行Maven的`test`目标时,Idea会自动识别并应用相应的profile。你也可以在Maven工具窗口中选择要使用的profile,或者在运行/调试配置中选择Maven目标并指定profile。 ...
- 利用Maven的 profiles 功能为不同的环境(如开发、测试、生产)创建不同的配置。 - 使用Maven的依赖管理,避免版本冲突。 - 配置合适的Maven镜像,提高下载速度。 总结来说,Maven 3.8.5为Linux用户提供了强大的...
通过使用Maven,开发者可以定义项目的结构、依赖关系和构建过程,只需编写一次配置,就能在不同的环境中一致地构建项目。其核心概念是项目对象模型(Project Object Model,POM),一个XML文件,描述了项目的基本...
- 使用Maven Profiles可以为不同的环境(如开发、测试、生产)创建不同的配置。 总之,Maven通过其强大的项目管理和自动化能力,极大地简化了Java项目的构建过程,提高了开发效率。无论是小型项目还是大型企业级...
** Maven使用手册 ** 在Java开发中,Maven是一个至关重要的工具,它简化了构建、管理和依赖关系的处理。这个“08Maven使用手册”将深入探讨如何有效地使用Maven,帮助开发者从项目的初始化到部署的每一个阶段都能...
- **使用Maven Profiles**:针对不同的环境(如开发、测试、生产)创建不同的配置档案。 - **持续集成**:与Jenkins、GitLab CI/CD等工具结合,实现自动化构建和部署。 总之,Maven 3.6.1作为一个成熟的项目管理...
** Maven2 中文使用手册 ** Maven 是一个强大的项目管理工具,主要应用于Java开发领域。它通过自动化构建过程,简化项目的构建、依赖管理和文档生成。Maven2 是 Maven 的第二个主要版本,虽然现在已经更新到了 ...
** Maven详细使用指南 ** Maven是一个强大的Java项目管理和依赖管理工具,它简化了构建、编译、测试、文档生成以及项目的部署等过程。本文将深入探讨Maven的核心概念、配置、生命周期、插件和仓库管理,帮助你全面...
1. **项目对象模型(POM)**:Maven 使用一个 XML 文件(通常是 `pom.xml`)来描述项目的基本信息、构建过程、依赖关系等。 2. **依赖管理**:Maven 能够自动处理项目所需的所有外部依赖,开发者不需要手动下载和...