这是一个Maven提高篇的系列,包含有以下文章:

  1. Maven提高篇系列之(一)——多模块 vs 继承
  2. Maven提高篇系列之(二)——配置Plugin到某个Phase(以Selenium集成测试为例)
  3. Maven提高篇系列之(三)——使用自己的Repository(Nexus)
  4. Maven提高篇系列之(四)——使用Profile
  5. Maven提高篇系列之(五)——处理依赖冲突
  6. Maven提高篇系列之(六)——编写自己的Plugin(本系列完)

在开发项目时,设想有以下场景:

  1. 你的Maven项目存放在一个远程代码库中(比如github),该项目需要访问数据库,你有两台电脑,一台是Linux,一台是Mac OS X,你希望在两台电脑上都能做项目开发。但是,安装Linux的电脑上安装的是MySQL数据库,而Mac OS X的电脑安装的是PostgreSQL数据库。此时你需要找到一种简单的方法在两种数据库连接中进行切换,你会怎么做?

  2. 此外,你的项目需要部署。为了调试,在开发时我们在Java编译结果中加入了调试信息(Java默认)。而在部署时你希望Java编译结果中不出现调试信息。此时你又会怎么做?

答案是Profile。Maven的Profile用于在不同的环境下应用不同的配置。一套配置即称为一个Profile。这里的“环境”可以是操作系统版本,JDK版本或某些文件是否存在这样的物理环境,也可以是你自己定义的一套逻辑环境。比如上面的A中所说的Linux和Mac OS X便是一种物理环境,而B中讲的开发环境和部署环境则为逻辑环境。Maven提供了Activation机制来激活某个Profile,它既允许自动激活(即在某些条件满足时自动使某个Profile生效),也可以手动激活。

一个Profile几乎可以包含所有能够出现在pom.xml中的配置项,比如<artifactId>,<outputDirectory>等。相当于在Profile中定义的配置信息会覆盖原有pom.xml中的相应配置项。

(一)定义Profile

一般来说,我们将Profile的定义放在pom.xml文件的最后:

<profiles>

       <profile>

           <id>apple</id>

           <activation>

               <activeByDefault>true</activeByDefault>

           </activation>

           <properties>

               <fruit>APPLE</fruit>

           </properties>

       </profile>

       <profile>

           <id>banana</id>

           <properties>

               <fruit>BANANA</fruit>

           </properties>

       </profile>

   </profiles>

在上面的配置中,我们定义了两个Profile,一个id为apple,该Profile将fruit属性设置为APPLE,另一个id为banana,它将fruit属性设置为BANANA。此外,第一个Profile还配置了“<activeByDefault>true</activeByDefault>”,表明该Profile默认即是生效的。

为了打印出fruit这个属性,我们再向pom.xml中添加一个maven-antrun-plugin插件,我们可以通过该插件的echo任务来打印属性信息。我们将该打印配置在Maven的initialize阶段(任何阶段都可以):

           <plugin>

               <artifactId>maven-antrun-plugin</artifactId>

               <executions>

                   <execution>

                       <phase>initialize</phase>

                       <goals>

                           <goal>run</goal>

                       </goals>

                       <configuration>

                           <tasks>

                               <echo>Fruit:${fruit}</echo>

                           </tasks>

                       </configuration>

                   </execution>

               </executions>

           </plugin>

配置完成之后,执行:“mvn initialize”,由于id为apple的Profile默认生效,此时将在终端输出“APPLE”字样:

......

[INFO] Executing tasks

    [echo] Fruit:APPLE

[INFO] Executed tasks

......

如果要使用id为banana的Profile,我们可以显式地指定使用该Profile:"mvn initialize -Pbanana":

......

[INFO] Executing tasks

    [echo] Fruit:BANANA

[INFO] Executed tasks

......

(二)手动激活Profile

事实上,在上面的例子中,我们在显示“BANANA”时便使用了手动激活Profile的方式。手动激活Profile要求我们在运行mvn命令时通过“-PprofileId”的方式指定使用某个Profile。比如,对于上文提到的B点,我们可以通过一下配置完成:

<profile>

<id>production</id>

<build>

   <plugins>

       <plugin>

           <groupId>org.apache.maven.plugins</groupId>

           <artifactId>maven-compiler-plugin</artifactId>

           <configuration>

               <debug>false</debug>

           </configuration>

       </plugin>

   </plugins>

</build>

</profile>

在开发时,我们使用“mvn clean install”,此时名为production的Profile并没有被激活,所以还是采用Java编译默认的配置(即在结果中包含了调试信息)。当需要为生产部署环境编译时,便可以使用“mvn clean install -Pproduction”。

本人认为,Maven的Profile机制最大的好处在于它的自动激活性(请参考下文),因为如果手动激活,在运行mvn命令时我们依然需要告诉Maven一些信息(即这里的“-PprofileId”)来完成配置,我们完全可以通过另外的方法来达到相同的目的。比如,我们可以定义一个父pom和两个子pom(比如pom.xml和pomB.xml),在父pom中我们存放两个子pom共享的配置(比如上面的maven-antrun-plugin),而在两个子pom中分别配置不同的信息以代表不同的环境,比如在pom.xml中(默认执行的pom),我们将fruit属性设置成APPLE,而在pomB.xml中,将fruit属性设置成BANANA。此时,pom.xml和pomB.xml都继承自父pom。虽然在默认情况下Maven会将名为“pom.xml”的文件作为输入文件,但是我们通过“-f”参数来指定其他pom文件。比如,如果我们要显示“APPLE”,我们可以直接执行“mvn initialize”,如果要显示“BANANA”,则可以执行“mvn initialize -f pomB.xml”。

(三)自动激活Profile

在自动激活Profile中,我们需要为某个Profile预先定义一些前提条件(比如操作系统版本),当这些前提条件满足时,该Profile将被自动激活。比如,对于上文中的A点,我们可以为Mac OS X和Linux(Unix)分别定义一套数据库连接:

       <profile>

           <id>mac</id>

           <activation>

               <activeByDefault>false</activeByDefault>

               <os>

                   <family>mac</family>

               </os>

           </activation>

           <properties>

               <database.driverClassName>org.postgresql.Driver</database.driverClassName>

               <database.url>jdbc:postgresql://localhost/database</database.url>

               <database.user>username</database.user>

               <database.password>password</database.password>

           </properties>

       </profile>

       <profile>

           <id>unix</id>

           <activation>

               <activeByDefault>false</activeByDefault>

               <os>

                   <family>unix</family>

               </os>

           </activation>

           <properties>

               <database.driverClassName>com.mysql.jdbc.Driver</database.driverClassName>

               <database.url>jdbc:mysql://localhost:3306/database</database.url>

               <database.user>username</database.user>

               <database.password>password</database.password>

           </properties>

       </profile>

请注意,以上两个Profile在默认情况下都没有被激活,Maven在运行时会检查操作系统,如果操作系统为Mac OS X,那么Maven将自动激活id为mac的Profile,此时将使用PostgreSQL的数据库链接,如果操作系统为Linux或Unix,那么将使用MySQL数据库连接。更多的Profile自动激活条件,请参考此文档

下一篇文章中,我们将讲到如何处理依赖冲突。

Maven提高篇系列之(四)——使用Profile的更多相关文章

  1. Maven提高篇系列之(六)——编写自己的Plugin(本系列完)

    这是一个Maven提高篇的系列,包含有以下文章: Maven提高篇系列之(一)——多模块 vs 继承 Maven提高篇系列之(二)——配置Plugin到某个Phase(以Selenium集成测试为例) ...

  2. Maven提高篇系列之(五)——处理依赖冲突

    这是一个Maven提高篇的系列,包含有以下文章: Maven提高篇系列之(一)——多模块 vs 继承 Maven提高篇系列之(二)——配置Plugin到某个Phase(以Selenium集成测试为例) ...

  3. Maven提高篇系列之(三)——使用自己的Repository(Nexus)

    这是一个Maven提高篇的系列,包含有以下文章: Maven提高篇系列之(一)——多模块 vs 继承 Maven提高篇系列之(二)——配置Plugin到某个Phase(以Selenium集成测试为例) ...

  4. Maven提高篇系列之(二)——配置Plugin到某个Phase(以Selenium集成测试为例)

    这是一个Maven提高篇的系列,包含有以下文章: Maven提高篇系列之(一)——多模块 vs 继承 Maven提高篇系列之(二)——配置Plugin到某个Phase(以Selenium集成测试为例) ...

  5. Maven提高篇系列之(一)——多模块 vs 继承

    这是一个Maven提高篇的系列,包含有以下文章: Maven提高篇系列之(一)——多模块 vs 继承 Maven提高篇系列之(二)——配置Plugin到某个Phase(以Selenium集成测试为例) ...

  6. Maven提高篇系列之五——处理依赖冲突

    个人分类: Maven 不知道你在使用Maven时是否遇到过诸如"NoSuchMethodError"或"ClassNotFoundException"之类的问 ...

  7. chessy 提高篇系列 阅读笔记

    java提高篇(一)—–理解java的三大特性之封装 封装的好处, 汇聚属性和方法 减少修改对 其他处的影响 控制get和set方法. java提高篇(二)—–理解java的三大特性之继承 继承的好处 ...

  8. java提高篇(十四)-----关键字final

    在程序设计中,我们有时可能希望某些数据是不能够改变的,这个时候final就有用武之地了.final是java的关键字,它所表示的是"这部分是无法修改的".不想被改变的原因有两个:效 ...

  9. java提高篇(二四)-----HashSet

          在前篇博文中(java提高篇(二三)-----HashMap)详细讲解了HashMap的实现过程,对于HashSet而言,它是基于HashMap来实现的,底层采用HashMap来保存元素. ...

随机推荐

  1. 设计模式之美:Behavioral Patterns(行为型模式)

    行为型模式涉及到算法和对象间职责的分配. 行为模式不仅描述对象或类的模式,还描述它们之间的通信模式. 这些模式刻划了在运行时难以跟踪的复杂的控制流.它们将你的注意力从控制流转移到对象间的联系方式上来. ...

  2. 《C#图解教程》读书笔记之四:类和继承

    本篇已收录至<C#图解教程>读书笔记目录贴,点击访问该目录可获取更多内容. 一.万物之宗:Object (1)除了特殊的Object类,其他所有类都是派生类,即使他们没有显示基类定义. ( ...

  3. 5天玩转C#并行和多线程编程 —— 第一天 认识Parallel

    5天玩转C#并行和多线程编程系列文章目录 5天玩转C#并行和多线程编程 —— 第一天 认识Parallel 5天玩转C#并行和多线程编程 —— 第二天 并行集合和PLinq 5天玩转C#并行和多线程编 ...

  4. 用curl向指定地址POST一个JSON格式的数据

    昨天的一个任务,用POST 方式向一个指定的URL推送数据.以前都用的数组来完成这个工作. 现在要求用json格式.感觉应该是一样的.开写. <?php $post_url = "ht ...

  5. 人机大战之AlphaGo的硬件配置和算法研究

    AlphaGo的硬件配置 最近AlphaGo与李世石的比赛如火如荼,关于第四盘李世石神之一手不在我们的讨论范围之内.我们重点讨论下AlphaGo的硬件配置: AlphaGo有多个版本,其中最强的是分布 ...

  6. Mybatis错误(一)org.apache.ibatis.exceptions.PersistenceException

    在映射文件中,通过parameterType指定输入参数的类型,类型可以是简单类型.hashmap.pojo的包装类型.在测试包装类型过程中产生了一个错误:org.apache.ibatis.exce ...

  7. Atitti usrQBf1801 翻页控件规范  v2

    Atitti usrQBf1801 翻页控件规范  v2 1. 参考api  参考easyui ,.net系列的1 1.1. 翻页流程  初始化翻页控件,以及绑定新页面event onSelectPa ...

  8. 选课数据库SQL语句练习题

    表(一)Student (学生表) 属性名 数据类型 可否为空 含 义 Sno varchar (20) 否 学号(主码) Sname varchar (20) 否 学生姓名 Ssex varchar ...

  9. 阿里云部署Java web项目初体验(转)/linux 上配置jdk和安装tomcat

    摘要:本文主要讲了如何在阿里云上安装JDK.Tomcat以及其配置过程.最后以一个实例来演示在阿里云上部署Java web项目. 一.准备工作 购买了阿里云的云解析,和云服务器ecs. 2.下载put ...

  10. Java-set集合

    package exception; import java.util.Map; import java.util.TreeMap; import java.util.HashMap; public ...