一、Maven 的生命周期

Maven 的生命周期是对所有的构建过程进行抽象和统一。Maven 的生命周期是抽象的,这意味着生命周期本身不做任何实际的工作,生命周期只是定义了一系列的阶段,并确定这些阶段的执行顺序。

Maven 有三套相互独立的生命周期,分别是 clean、default和 site。生命周期( lifecycle )由多个阶段( phase )组成,每个阶段( phase )会挂接一到多个goal。Goal 是 maven 里定义任务的最小单元,如下表:

生命周期( Lifecycle )

阶段( Phase )

目标( Goa l)

clean

clean

maven-clean-plugin:clean

default

process-resources

maven-resources-plugin:resources

compile

maven-compiler-plugin:compile

generate-test-resources

maven-resources-plugin:testResouces

test-compile

maven-compiler-plugin:testCompile

test

maven-surefire-plugin:test

package

打包类型是jar时:maven-jar-plugin:jar;

打包类型是war时:maven-war-plugin:war

install

maven-install-plugin:install

deploy

maven-deploy-plugin:deploy

site

site

maven-site-plugin:site

site-deploy

maven-site-plugin:deploy

二、 Maven 插件和生命周期的绑定

Maven 的插件位于 ${REPOSITORY_HOME}\org\apache\maven\plugins 。用户和 Maven 最直接的交互方式就是调用这些生命周期阶段,而在执行这些阶段时,实际的任务主要由插件来完成。

  1. 以 Phase 为目标的构建
    以 phase 为目标进行构建是最常见的,如我们平时经常执行的 mvn compile,mvn test,mvn package...等等, compile, test, package 都是 maven 生命周期( lifecycle )里的 phase,通过 mvn 命令,你可以指定一次构建执行到哪一个阶段,在执行过程中,所有经历到的执行阶段( phase )上绑定的 goal 都将得到执行。例如,对于一个jar包应用,当执行mvn package命令时,maven 从 validate 阶段一个阶段到一个阶段的执行,在执行到 compile 阶段时,compiler 插件的 compile goal 会被执行,因为这个 goal 是绑定在compile阶段( phase )上的。这一点可从其对应的 mojo 类上得知:

    再比如经常使用的打包插件 shade,它的 goal 是绑定到package阶段的,这样,使用 mvn package 进行打包时都会执行 shade 的。
  2. 以 Goal 为目标的构建
    虽然以 phase 为目标的构建最常见,但是有时候我们会发现,一些插件的 goal 并不适合绑定到任何阶段( phase )上,或者是这些 goal 往往是单独执行,不需要同某个阶段( phase )绑定在一起,比如 jetty(6.1.26)插件,它的 goal 都是将打包或未打包的工程部署到 jetty 里然后启动 jetty 容器的,多数情况下,人们都是独立运行这些goal的,比如:人们希望当键入 mvn jetty:run 后,工程就能完成编译后启动 jetty。而 jetty 插件也确实是这样做的,它的 run goal 的 mojo 是这样声明的:

    其中 @execute phase="test-compile" 指明 jetty:run 这一 goal 会促使 maven 先 build 到 test-compile 阶段,再执行这个 goal。同样,对于 jetty:run-war 这个goal 则要求先 build 到 package 阶段再执行该 goal。

    而另外一个例子是exec插件的exec:java.

    这个 goal 也声明了 execute 的 phase,但却是 validate,这样,如果代码没有编译,执行这个 goal 就会出错,所以多数情况下,人们总是使用下面的方式执行的:mvn clean compile exec:java
    Maven 支持这种方式是因为有些任务不适合绑定到生命周期上。
    在命令行调用插件的格式如下:
      mvn groupId:artifactId:version:goal
    其中 groupId、artifactId、version 共同表示了插件的坐标,goal 则表示插件目标的方法。
    但我们看到很多执行插件目标的格式与之并不相符,例如文章开头的 mvn jetty:run,jetty并不是 groupId、artifactId或version 而是插件的前缀,这就有了第二种调用插件的格式:
      mvn 前缀:goal

    Maven 通过查询插件仓库的元数据才得知插件前缀对应插件的 groupId、artifactId,而如果插件是Maven的核心插件则在超级POM中已经定义了插件的版本,如果不是核心插件,则默认取最新的release版本 。
    Maven的插件仓库默认是 http://repo1.maven.org/maven2/org/apache/maven/plugins/ 和 http://repository.codehaus.org/org/codehaus/mojo/,相应的查询插件仓库元数据时会默认使用 org.apache.maven.plugins 和 org.codehaus.mojo 两个 groupId。但也可以通过配置 settings.xml 让Maven检查其他 groupId 上的插件仓库元数据,如:

    <settings>
    <pluginGroups>
    <pluginGroup>com.your.plugins</pluginGroup>
    </pluginGroups>
    </settings>

    这样配置后,Maven就不只检查 org/apache/maven/plugins/maven-metadata.xml 和 org/codehaus/mojo/maven-metadata.xml,还会检查com/your/plugins/maven-metadata.xml

  3. 相关配置实例
    如果我们想在 test 阶段只执行单元测试,而在 integration-test 阶段进行集成测试的话,可以如下配置:
    <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.10</version>
    <configuration>
    <skip>true</skip>
    </configuration>
    <executions>
    <execution>
    <id>run-test</id>
    <phase>test</phase>
    <goals>
    <goal>test</goal>
    </goals>
    <configuration>
    <skip>false</skip>
    <includes>
    <include>**/unit/**/*.java</include>
    </includes>
    </configuration>
    </execution>
    <execution>
    <id>run-integration-test</id>
    <phase>integration-test</phase>
    <goals>
    <goal>test</goal>
    </goals>
    <configuration>
    <skip>false</skip>
    <includes>
    <include>**/integration/**/*.java</include>
    </includes>
    </configuration>
    </execution>
    </executions>
    </plugin>

    其中红色背景的 <skip>true</skip> 是为了让 Maven 的默认绑定(test阶段<-> maven-surefire-plugin:test 插件目标) 无效 (其实绑定仍然有效,只是执行时忽略执行罢了),而后面的 executions 块内容则增加了两个绑定,分别将 maven-surefire-plugin:test 插件目标绑定到 test 阶段和 integration-test 阶段,只是配置不一样了,分别执行unit包和integration包下的测试类。

三、参考文档

Maven 的插件和生命周期的绑定的更多相关文章

  1. maven的仓库、生命周期与插件

    一.仓库 统一存储所有Maven项目共享的构建的位置就是仓库. 仓库分为本地仓库和远程仓库.远程仓库又分为中央仓库(中央仓库是Maven核心自带的远程仓库),伺服(另一种特殊的远程仓库,为节省宽带和时 ...

  2. maven详解之生命周期与插件

    Maven是一个优秀的项目管理工具,它能够帮你管理编译.报告.文档等. Maven的生命周期: maven的生命周期是抽象的,它本身并不做任何的工作.实际的工作都交由"插件"来完成 ...

  3. maven插件的生命周期的详细说明(两)

    插件配置 定义解释:插件目标 当我们了解了maven插件之后.我们发现假设为每个功能编写一个独立的插件显然是不可取的,由于这些任务背后有非常多能够复用的代码.因此,把这些功能聚集在一个插件里,每个功能 ...

  4. maven的核心概念——生命周期

    第十一章生命周期 11.1 什么是Maven的生命周期 ●Maven生命周期定义了各个构建环节的执行顺序,有了这个清单,Maven就可以自动化的执行构建命令了. ●Maven有三套相互独立的生命周期, ...

  5. Service的生命周期&Service绑定方法

    服务的生命周期: 一.采用start的方式开启服务 生命周期如下: 开启服务: onCreate()--> onStartCommand() (onStart()过时了)---> onDe ...

  6. maven第7章生命周期和插件

    maven插件用到哪些思想? 7.7 从命令行调用插件 目标前缀和插件前缀是一个意思. 在本地搭建maven环境,熟悉maven的环境.

  7. maven build的常用生命周期

    常用的maven build goals: validate - validate the project is correct and all necessary information is av ...

  8. Maven入门 项目的生命周期&pom.xml配置&仓库

  9. Maven 学习总结 (二) 之 生命周期与插件

    五.生命周期与插件 1.Maven有三套独立的生命周期:clean.default和site. clean生命周期的目的是清理项目,default生命周期的目的是构建项目,site生命周期的目的是建立 ...

随机推荐

  1. XPath函数——字符串函数(转载)

    本文是转载的,原文网址:http://www.cnblogs.com/zhaozhan/archive/2010/01/17/1650242.html 字符串函数主要用来处理字符串.字符串函数主要包括 ...

  2. ztree.js的使用整理

    /** 配置:知识点管理 */ var setting = { view: { showIcon: false, addDiyDom: addPrevDom, addHoverDom: addHove ...

  3. 交换机--Switch

    交换机(Switch)意为"开关"是一种用于电(光)信号转发的网络设备.它可以为接入交换机的任意两个网络节点提供独享的电信号通路.最常见的交换机是以太网交换机. 这里的" ...

  4. 11月3日上午PHP练习《投票》

    1.建立数据库 表1:DiaoYanTiMu 表2:DiaoYanXuanXiang 2.页面 页面1:投票首页 <!DOCTYPE html PUBLIC "-//W3C//DTD ...

  5. Dapper.Net 应用

    Dapper应用 1.Dapper是什么 Dapper是一款轻量级ORM工具.如果你在小的项目中,使用Entity Framework.NHibernate 来处理大数据访问及关系映射,未免有点杀鸡用 ...

  6. UIScrollView和delegate的通信

    在OC中,发送消息的意思就是调用方法 因此UIScrollView和delegate的通信可以理解为下图所示 再精确一点,UIScrollView和delegate的通信应该为下图所示 可以看出,要想 ...

  7. Development of large-scale site performance optimization method from LiveJournal background

    A LiveJournal course of development is a project in the 99 years began in the campus, a few people d ...

  8. C和指针 第十二章 使用结构和指针 双链表和语句提炼

    双链表中每个节点包含指向当前和之后节点的指针,插入节点到双链表中需要考虑四种情况: 1.插入到链表头部 2.插入到链表尾部 3.插入到空链表中 4.插入到链表内部 #include <stdio ...

  9. C和指针 第十章 结构和联合 习题

    1. 记账信息结构联合 typedef struct { unsigned int areaNum; unsigned int transNum; unsigned int station; } ph ...

  10. java环境配置为1.7jdk为什么cmd java -version查看版本是1.8

    记录一个小问题: 初始安装的是jdk1.8,后来项目需要要更换成jdk1.7, 因此将环境变量更改为jdk7的目录路径, 但是在cmd命令行运行java -version 发现还是jdk8 解决方法: ...