【Maven】【翻译】3、Profiles文件

本文根据 Maven profiles文件介绍翻译:

一、构建Profiles配置文件介绍;

Apache Maven 2.0 工程在保证构建过程更便捷起了非常大的作用;除了其他特例,它允许在POM里构建配置,这样就避免了所有文件系统相关的麻烦(继承,依赖和其他地方),并且避免在本地仓库学习太多来存储实现的原始数据;

然鹅,有时候可移植性是不完全支持的;在某些情况下,插件可能需要在本地文件系统路径下配置。另一些情况下,一个些轻微不同的依赖设置是必须的,并且项目的产品名称可能需要做轻微的调整。并且在其他时候,在扫描构建环境的时候,你可能甚至需要包括构建Maven生命周期的所有插件的依赖;

为了定位这些情况,Maven2.0引入了profile的概念;profiles是为了POM文件自身(可能还有其他部分)中可用元素而特别定义的;并且会被多种途径触发;在构建时期,他们会修改POM文件,并且被用来完善设置目标环境等价但是不完全相同的参数(例如,开发,测试和生产环境app服务器的根目录);因此,profiles可以轻易的搭建一个你团队不同成员的不同构建结果;然而,正式使用时,profiles可以在保留项目可移植性而使用。这会尽量减少-f 操作(Maven允许用户根据不同的参数或配置创建另一个POM,以此在唯一一个POM运行时,来构建可维护性 )

二、profile类型之间的不同,每个是在哪定义的;

  • 每个项目 :在POM文件本身里定义(pom.xml).
  • 每个用户:在Maven的settings文件里定义 (%USER_HOME%/.m2/settings.xml).
  • 全局配置: 在全局的Maven的settings 文件里配置(${maven.home}/conf/settings.xml).
  • 在Profile定义:一个定义在项目根目录中的脚本 (profiles.xml) (Maven 3.0中不支持:详情参看 Maven 3 compatibility notes)

三、一个profile怎样被触发的?根据已用的profile类型如何变化的?

一个profile文件可以被以下几种情况出发:

  • 明确定义
  • 通过Maven的settings文件配置
  • 机遇环境变量
  • OS的settings文件
  • 存在或丢失文件
    3.1、profile操作详解
    Profiles可以通过CLI命令行操作,使用-p 命令。
    这个操作需要你使用用逗号分隔的profile文件的ID。当这个动作被定义了,profiles文件会定义动作,并且在任何profiles文件中可以通过激活配置或者通过settings.xml文件中的<activeProfiles>标签来被激活;
mvn groupId:artifactId:goal -P profile-1,profile-2

Profiles文件可以在Maven的settings文件中,通过<activeProfiles>标签来激活;这个标签可以通过<activeProfile> 标签,每个标签里都包含profile文件的ID;举例如下:

<settings>
  ...
  <activeProfiles>
    <activeProfile>profile-1</activeProfile>
  </activeProfiles>
  ...
</settings>

Profiles在<activeProfiles>标签里会在每次该项目被使用时激活;
Profiles在构建环境是,可以被侦测到并自动激活;这个触发器会被定义在profile文件的<activeProfiles> 标签里;目前,这个标签被JDK的版本,系统性能的表现或系统性能的值所限制;下面是例子

<profiles>
  <profile>
    <activation>
      <jdk>1.4</jdk>
    </activation>
    ...
  </profile>
</profiles>

在Maven 2.1中,可以被使用的范围(可以查找Enforcer Version Range Syntax 获取更多信息)。下面的是1.3,1.4,1.5版本的;

<profiles>
  <profile>
    <activation>
      <jdk>[1.3,1.6)</jdk>
    </activation>
    ...
  </profile>
</profiles>

注意:一个更高的边界,例如 ,1.5] 更可能不包括1.5。自从他们添加了额外的patch发行版,例如 _05,是不被上面的范围考虑进去的;
下一个会被激活的情况是OS(Operating System-操作系统)的settings配置文件;请参看Maven Enforcer Plugin 获取关于OS值详情的信息;

<profiles>
  <profile>
    <activation>
      <os>
        <name>Windows XP</name>
        <family>Windows</family>
        <arch>x86</arch>
        <version>5.1.2600</version>
      </os>
    </activation>
    ...
  </profile>
</profiles>

下面可以通过系统属性的【debug】的值来特别定义,使prifile被激活:

<profiles>
  <profile>
    <activation>
      <property>
        <name>debug</name>
      </property>
    </activation>
    ...
  </profile>
</profiles>

下面通过系统属性的【debug】模式不能激活profile

<profiles>
  <profile>
    <activation>
      <property>
        <name>!debug</name>
      </property>
    </activation>
    ...
  </profile>
</profiles>

如果配置了系统属性没有定义【debug】或者定义了【debug】属性,但是值为非真,那么也不会激活;

    <profiles>
      <profile>
        <activation>
          <property>
            <name>debug</name>
            <value>!true</value>
          </property>
        </activation>
        ...
      </profile>
    </profiles>

为了激活,你需要在CLI命令行输入下面命令之一:

mvn groupId:artifactId:goal
mvn groupId:artifactId:goal -Ddebug=false

下一个例子可以通过定义环境系统属性为test,来激活配置

<profiles>
  <profile>
    <activation>
      <property>
        <name>environment</name>
        <value>test</value>
      </property>
    </activation>
    ...
  </profile>
</profiles>

为了激活该配置,你需要在CLI命令行执行下面命令:

mvn groupId:artifactId:goal -Denvironment=test

在Maven 3.0版本中,POM中的profiles文件可以通过settings.xml文件中的属性来激活:
注意:环境变量中的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> and <missing>的值可以被修改的,支持例如 ${user.home} 这样的系统变量,例如${env.HOME}的环境变量。注意定义在POM文件中的属性和值是不允许修改的;上面的例子激活器不能够使用${project.build.directory},但是需要硬式编码target的路径;
Profiles 可以同样的被下面的配置激活

<profiles>
  <profile>
    <id>profile-1</id>
    <activation>
      <activeByDefault>true</activeByDefault>
    </activation>
    ...
  </profile>
</profiles>

这个profile可以自动的被所以编译自动激活,除非另一个相同的POM文件中有一个profile已经有限描述了该方法被激活了。当一个POM文件中的profile文件通过CLI命令或者配置被激活,所有的profiles文件会被默认自动激活,自动失效;
3.1、失效一个profile文件
Maven 2.0.10开始,可以通过CLI命令来预配置他们的【!】或者【-】标识符,来使一个或多个profiles文件可以被失效,举例如下:

mvn groupId:artifactId:goal -P !profile-1,!profile-2

这可以是profiles文件被activeByDefault失效,否则profiles将会被激活配置激活;

四、POM文件中哪个地方可以被profile自定义?为什么?

现在,我们谈了怎样特别定义一个profiles,并且如何激活他们,讨论如何定义一个profile文件很有意义;profile文件配置的其他方面,这里答案是不明确的;
依赖于你再profile文件中选择的配置,你会有多重配置POM选项;

4.1、外部文件的Profiles
在外部文件定义profiles文件(例如settings.xml或profiles.xml)严格意义上说是不便捷的;任何在POM正文里的构建结果,看上去改变的可能性很大;像repository仓库列表一样思考,它可以很简单的被严格垄断认证,并且不会改变构建的结果;因此,你可以仅仅修改<repositories> and <pluginRepositories> 标签,外加一个<properties>标签;

<properties>标签允许你特别定义自由格式的键值对,这些键值对会被包括在POM文件中。这允许你以${profile.provided.path}的形式来定义你的插件配置;

4.2、POMs文件中的Profiles;
另一方面,如果你的profiles文件可以在POM文件里合理的定义,你可以有多重选择;权衡利弊,你可以仅仅修改项目和子模块;自从这些profiles文件可以在POM内部定义,因此有更好的机会保证其可移植性;你添加更多的信息而不带来其他用户不可使用的风险是非常合理的;

POM文件中的Profiles文件可以修改下列标签:

<repositories>
<pluginRepositories>
<dependencies>
<plugins>
<properties> (不仅仅在主POM文件,并且可以被用在场景后)
<modules>
<reporting>
<dependencyManagement>
<distributionManagement>
<build>标签的子集, 由下列标签组成:
<defaultGoal>
<resources>
<testResources>
<finalName>

4.3、<profiles> 标签外的POM文件
我们不允许在POM的profiles文件外修改POM标签,因为这些运行时修改,在POM部署到仓库系统时不会是分布的,会使一个人构建的项目和其他人不一样;当你通过外部profiles文件来操作某些场景时,风险是可控的;另一个原因是POM文件信息可以被父POM复用;

外部文件,例如settings.xml和profiles.xml文件同时不支持外部的POM的profiles文件。让我们精心构建下场景。当有效的POM文件从一个远程的仓库部署时,任何人可以在仓库外获取其信息,并且使用这些来直接构建一个Maven项目。现在,想象一下,我们可以在依赖中设置profiles文件,这对于构建来说,很重要。或者,在settings.xml文件中的,POM的profiles之外的标签,最可能的是,我们不希望其他使用仓库的POM,并且可以构建它。我们还考虑到如何跟其他人分享settings.xml;注意,再多的配置文件会让人混乱并且难以维护。我们的底线是,只要开始构建数据了,它必须在POM中。Mavne 2的一个目标就是巩固需要运行的单个文件的构建,或者让POM文件分级;

五、profile陷阱;

我们已经提到了一个事实,添加profiles文件来构建有破坏可移植性的潜在风险。我们甚至强调了概要文件可能破坏项目可移植性的情况。然而,重申这些关于一些避坑的,重点清晰的论点是非常有意义的;

当你使用profiles时,这里有两个主要的问题必须注意;
1、外部的属性,通常在插件配置中。这会造成你项目可移植性变差;
2、更微妙的领域是对一组自然概要文件的不完整规范。

5.1、外部属性
额外的属性定义设计定义在POM.xml文件外的任何属性值的定义,但是没定义在同一个profiles文件里的;这通常能在POM中的插件配置里看到属性的使用;当没有属性时,很可能会破坏其可移植性,这些怪异可以以微妙的影响造成构建失败;例如,只在settings.xml文件中的profile中指定了app服务器的路径,当另一个团队用户试图在没有类似的settings.xml文件的情况下构建,可能导致你的集成测试插件失败;考虑到下面的pom.xml ,一个为web程序项目的片段

<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>

在你本地的${user.home}/.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>

当你构建集成测试生命周期阶段,你的集成测试通过,在这个你提供的允许测试插件来安装和测试web项目的路径。
然而,当你同时试图构建集成测试时,他构建却惨烈地失败了,抱怨这个不能解析<appserverHome> 这个参见配置参数,甚至更糟糕的是,合法的参数的值${appserver.home} 却获取不到;

值得庆幸的是,你的项目现在不可移植。在profile文件里嵌入你的pom.xml文件可以帮助缓和这个情况,这里明显的缺陷是,每个项目的层级(允许继承的影响)都会明确这些信息。自从Maven为项目继承提供了很好的支持,它允许团队级别在POM文件添加这种<pluginManagement> 标签,并且简单继承这种路径;

另外,更少的吸引人的答案可能让开发环境更标准化;然而,这会增加对Maven开发效率的妥协;

5.2、不完善的自然的profile配置说明
除了上面的可移植性破坏,覆盖所有profiles文件会很容易导致失败;当你做这部分工作时,你常常会使你的目标环境很高和枯燥。下面举了一个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>

现在,考虑到下面的profiles,这个可以在pom.xml的正文里定义:

<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>

这个profiles配置文件看上去和上个例子很相似,但是有一点导入异常:它明确地与开发环境相适应;一个新的名为appserverConfig-dev-2 的profile文件被添加,并且它有一个激活的标签,在名为 appserverConfig-dev 的profile里,系统属性包含env=dev 和在名为 appserverConfig-dev2 的profile里包含系统属性 env=dev-2;这会使得它在内部出发;所以,执行以下命令

mvn -Denv=dev-2 integration-test

会导致成功构建,应用名为 appserverConfig-dev-2 的 profile,并且我们需要执行

mvn -Denv=dev integration-test

在应用了名为 appserverConfig-dev 的profile文件所给定属性,他讲构建成功。然后执行:

mvn -Denv=production integration-test

这不会构建成功。为什么?因为${appserver.home} 是不允许修改的;这不是一个你web项目部署和测试的有效的路径。我们在写profiles文件是不考虑产品环境的情况。产品环境指的是 env=production ,而且还可以是“test”,并且甚至可能是“local”组成的一个为我们可能构建的集成测试的生命周期阶段的自然的目标环境集合;未完成的自然集合的声明意味着我们可以有效的限额的可获得的开发的目标环境;你的同事-或者你的经历-将不再看到你的笑话;当你构造profiles文件来处理这些情况时,只要确认添加了完整的目标列表地址集即可;

顺便提一下,这允许用户使用自定义的profiles在相似环境开发;这意味着,profiles用来处理不同的环境是用户可以成功添加新开发者的关键;我支持这样用来训练网络新手,把他们像绵羊一样丢给狼群可能显得不太友好,但是,要考虑到整体的profiles集合;

六、我如何辨别构建过程中哪些profiles是有效的?

决定有效的profiles文件可以帮助用户知道在构建过程中,哪些profiles文件可以被执行。我们可以使用Maven Help Plugin 来告诉我们构建过程中哪些profiles是有效的;

mvn help:active-profiles

让我们举一些小例子来帮助我们理解这个插件中的有效profiles。
上一个pom.xml里profiles的例子,你需要注意,这里有两个profiles的标签:appserverConfig-devappserverConfig-dev-2 ,这样可以为属性赋不同的值。如果我们继续执行:

mvn help:active-profiles -Denv=dev

这个结果会执行激活所有定义了的状态的属性为 env=dev 的所有profiles列表;

The following profiles are active:
 
 - appserverConfig-dev (source: pom)

现在,如果我们有一个定义在settings.xml 里的profile文件(关联settings.xml中的profile配置例子),并且有一个激活的profile文件来执行;

  mvn help:active-profiles

结果会如下所示:
The following profiles are active:

  • appserverConfig (source: settings.xml)

尽管我们没有配置激活属性,但是一个激活的profile列表已经被激活了。为什么?像我们之前提到过的一样,一个settings.xml中设置的profile标签会自动被激活;

现在,如果我们有settings.xml文件中的profile文件,并且被设置成激活的profile,而且已经在POM中被触发了;你猜哪个在构建会生效?

 mvn help:active-profiles -P appserverConfig-dev

结果会显示如下:
The following profiles are active:

  • appserverConfig-dev (source: pom)
  • appserverConfig (source: settings.xml)

尽管,它列出了两个profiles部分,但是我们不缺定哪个被应用了;请看构建执行时的生效状态:

  mvn help:effective-pom -P appserverConfig-dev

它会打印出构建配置的有效的POM文件到控制台;注意settings.xml中的profiles会比POM中的profiles文件具有更高的权限;所以被应用的是appserverConfig 而非 appserverConfig-dev

如果你想重定向插件到一个名为 effective-pom.xml 的插件,使用命令行操作:

-Doutput=effective-pom.xml

七、命名惯例;

现在,你注意到profiles是一个很自然的为不同的目标环境,将不同的构建配置添加问题;以上,我们讨论了【自然配置】profilesl来添加这些情景,并且意识到profiles需要的所有设置的重要性;

然而,如何组织和管理版本演化也是非常重要的。就像一个优秀的开发者会【自我文档化】编码;在设计使用时给你的profiles部分的id会给出重要提示是非常重要的。一个很好的方法就是使用普通系统属性触发器作为profile的部分名字;这会导致,使一些像env-dev,env-test和env-prod作为profiles文件名能够被系统属性env出发;例如一个系统留下了凭直觉给提示:如何在一个特定的环境里激活一个构建目标。因此,要激活一个测试环境的构建,你需要激活 env-test 来驱动;

mvn -Denv=test <phase>

这种正确的命令行操作可以简单的被“=”来取代profile部分的id中的“-”;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值