Maven学习笔记(十二)生命周期和插件

来源:互联网 发布:广联达软件百度云 编辑:程序博客网 时间:2024/05/18 00:42

生命周期和插件

    除了坐标、依赖以及仓库之外,Maven的另外两个核心概念是生命周期和插件。在Maven 的日常使用中,命令行的输入往往就对应了生命周期。Maven 的生命周期是抽象的,其实际行为都由插件来完成。生命周期和插件两者协同工作。

什么是生命周期

    Maven 的生命周期就是为了对所有的构建过程进行抽象和统一。Maven总结大量项目和构建工具的经验,使其成为一套高度完善的、易扩展的生命周期。这个生命周期包含了项目的清理、初始化、编译、测试、打包、集成测试、验证、部署和站点生成等几乎所有的构建步骤。也就是说基本的项目构建都能映射到这样一个生命周期上。    Maven 的生命周期是抽象的,这意味着生命周期本身不做任何实际的工作。在Maven 的设计中,实际的任务(如编译源代码)都交由插件来完成。这种思想与设计模式中的模板方法(Template Method)非常相似。模板方法模式在父类中定义算法的整体结构,子类可以通过实现或者重写父类的方法来控制实际的行为,这样既保证了算法有足够的可扩展性,又能够严格控制算法的整体结构。    如下代码所示:
package com.my.template.method;public abstract class AbstractBuild {    public void build() {        initialize();        compile();        test();        packagee();        integrationTest();        deploy();    }    protected abstract void deploy();    protected abstract void integrationTest();    protected abstract void packagee();    protected abstract void test();    protected abstract void compile();    protected abstract void initialize();}
    生命周期抽象了构建的各个步骤,定义了它们的次序,但是没有提供具体实现。    为了不让用户为了编译写一套代码,为了测试又写一堆代码,因此它设计了插件机制。每个构建步骤都可以绑定一个或者多个插件行为,而且Maven为大多数构建步骤绑定了默认的插件。例如针对编译的有maven-compile-plugin,针对测试有maven-surefire-plugin等。当用户有特殊需要的时候,也可以配置插件定制构建行为,甚至自己编写插件。    生命周期与插件的关系如下图所示:

这里写图片描述

生命周期详解

三套生命周期:

    Maven拥有三套项目独立的生命周期,它们分别为clean、default和site。clean生命周期的目的是清理项目,default生命周期的目的是构建项目,而site生命周期的目的是建立项目站点。    每个生命周期包含一些阶段,这些阶段是有顺序的,并且后面的依赖于前面的阶段。用户和Maven最直接的交互方式就是调用这些生命周期阶段。    较之于生命周期阶段的前后依赖关系,三套生命周期本身是项目独立的,用户可以仅仅调用clean生命周期的某个阶段,或者仅仅调用default生命周期的某个阶段,而不会对其他生命周期产生任何影响。       clean生命周期    clean生命周期的目的是清理项目,它包含三个阶段:           pre-clean执行一些清理前需要完成的工作           clean清理上一次构建生成的文件           post-clean执行一些清理后需要完成的工作       default生命周期    default生命周期定义了真正构建时所需要执行的所有步骤,它是所有生命周期中最核心的部分,其包含的阶段如下,这里只对核心部分进行解释           validate           initialize           generate-source           process-sources 处理项目主资源文件。一般来说是对src\main\resources目录的内容进行变量替换等工作后,复制到项目输出的主classpath目录中。           generate-resource           process-resource           compile 编译项目的主源码。一般来说是编译src\main\java目录下的Java文件至项目输出的主classpath目录中           process-classes           generate-test-sources           process-test-source 处理项目测试资源文件。一般来说,是对src\test\resource目录下的内容进行变量替换等工作后,复制到项目输出的测试classpath目录中。           generate-test-resources           process-test-resources           test-compile 编译项目的测试代码。一般来说,是编译src\test\java目录下的java文件至项目输出的测试classpath目录中           process-test-classes           test 使用单元测试框架运行测试,测试代码不会被打包或部署           prepare-package           package 接受编译好的代码,打包成可发布的格式,如JAR           pre-integration-test           post-integration-test           verify           install 将包安装到Maven本地仓库,供本地其他Maven项目使用。       site生命周期    site生命周期的目的是建立和发布项目站点,Maven能够基于POM所包含的信息自动生成一个友好的站点,方便团队交流和发布项目信息。该生命周期包含如下阶段:           pre-site 执行一些在生成项目站点之前需要完成的工作           site 生成项目站点文档           post-site 执行一些在生成项目站点之后需要完成的工作           site-deploy 将生成的项目站点发布到服务器上

命令行与生命周期:

    从命令行执行Maven任务的主要方式就是调用Maven的生命周期阶段。需要注意的是,各个生命周期是相互独立的,而一个生命周期的阶段是有前后依赖关系的。    命令:mvn clean 命令执行过程与依赖关系如下所示:

这里写图片描述

    概括的说,当你调用某一个生命周期的一个阶段时,那么该阶段所依赖的上级阶段会依次执行至目标阶段。    由于Maven中主要的生命周期阶段并不多,而常用的Maven命令实际都是基于这些阶段简单组合而成,因此只要对Maven生命周期有一个基本的理解,就可以正确的使用Maven命令。

插件目标

    Maven的核心仅仅定义了抽象的生命周期,具体的任务是交由插件完成的,插件以独立的构件形式存在,因此Maven的核心的分发包只有不到3MB大小,Maven会在需要的时候下载并使用插件。    对于插件本身而言,为了能够复用代码, 它往往能够完成多个任务,例如maven-dependency-plugin,它能够基于项目依赖做很多事情,它能够分析项目依赖,帮助找出潜在的无用依赖,它能够列出项目的依赖树,帮助分析依赖来源,能够列出项目所有已解析的依赖等等。这些功能背后有大量的重复的代码,因此将它们放在一个插件里,每个功能就是一个插件目标。    我们平时使用的命令 mvn compiler其实就是对应了maven-compile-plugin的compile目标。

插件绑定

    Maven的生命周期与插件相互绑定,用以完成实际的构建任务。具体而言,是生命周期的阶段与插件的目标相互绑定,以完成某个具体的构建任务。例如项目编译这个任务,它对应了default生命周期的compile这一阶段,而maven-compiler-plugin这一插件的compile目标能够完成该任务,因此将它们绑定,就能实现项目编译的目的。如下图所示:

这里写图片描述

内置绑定

    为了能让用户几乎不用任何配置就能构建Maven项目,Maven在核心为一些主要生命周期阶段绑定了很多插件的目标,当用户通过命令行调用生命周期阶段你的时候,对应的插件目标就会执行相应的任务。    以clean生命周期阶段与插件目标的绑定关系为例,其关系如下:

这里写图片描述

自定义绑定

    除了内置的绑定,用户还能够自己选择某个插件目标绑定到生命周期的某个阶段上,这种自定义绑定方式能让Maven项目在构建过程中执行更多更富特色的任务。    一个常见的例子是创建项目的源码jar包,内置的插件绑定关系中并没有涉及这一任务,因此需要用户自行配置。    插件maven-source-plugin可以帮助我们完成该任务,他的jar-no-fork目标能够将项目的主代码打包成jar文件,可以将其绑定到default生命周期的verify阶段上,在执行完集成测试后和安装构件之前创建源码jar包,具体配置如下:

这里写图片描述

    上述的配置中,除了基本的声明外,还有插件执行配置,executions下每个execution子元素可以用来配置执行一个任务。上面代码中配置了一个id为attach-source的任务,通过phrase配置,将其绑定到verify生命周期阶段上,再通过goals配置指定要执行的插件目标。因此自定义插件绑定完成,运行mvn verify就能看到如下输出:

这里写图片描述

    有时候即使不通过phase元素配置生命周期阶段,插件目标也能够绑定到生命周期中去,例如删除上面配置中的phase这一行,重新执行命令,可以看到如下输出:

这里写图片描述

    出现这种现象的原因在于很多插件目标在编写时已经定义了默认绑定阶段。    我们了解到,当插件目标被绑定到不同生命周期阶段的时候,其执行顺序会由生命周期阶段的先后顺序决定。如果多个目标被绑定到同一个阶段,它们的执行顺序会是怎样?其实答案很简单,当多个插件绑定到同一个阶段的时候,这些插件声明的先后顺序决定了目标的执行顺序。    ----------------------未完待续--------------------------

插件配置

获取插件信息

从命令行调用插件

插件解析机制

总结:

0 0
原创粉丝点击