Maven的生命周期详解

本篇文章重点针对这几个问题进行讲解:

  • maven的生命周期都有哪些阶段?
  • maven的生命周期和插件到低有什么关联?
  • 插件和插件的目标有什么关联?
  • 假如我们要用某个插件,怎么上官网查找?
  • 怎么手动调用插件?

一、生命周期(clean+site+default)

在 Maven 出现之前,项目构建的生命周期就已经存在,开发人员每天都在对项目进行清理,编译,测试及部署,但由于没有统一的规范,不同公司甚至不同项目之间的构建的方式都不尽相同。

Maven 从大量项目和构建工具中学习和反思,最后总结了一套高度完美的,易扩展的生命周期。这个生命周期将项目的清理、初始化、编译、测试、打包、集成测试、验证、部署和站点生成等几乎所有构建过程进行了抽象和统一。

1、生命周期与插件的关系

Maven 生命周期是抽象的,其本身不能做任何实际工作,这些实际工作(如源代码编译)都通过调用 Maven 插件 中的插件目标(plugin goal)完成的。

为了更好的理解 Maven 生命周期、插件以及插件目标三者的关系,我们可以将 Maven 生命周期理解成一个抽象父类将插件理解成其子类将插件目标理解成子类中重写的方法,其基本结构与下面的示例代码相似。

/**
* 模拟 maven 生命周期
*/
public abstract class LifeCycle {
    
    
    //定义构建过程
    public void build() {
    
    
        //模拟生命周期各个阶段,即调用插件中目标
        clean();
        initialize();
        compile();
        packager();
        install();
    }

    //定义清理的过程
    public abstract void clean();

    //定义初始化的过程
    public abstract void initialize();

    //定义编译的过程
    public abstract void compile();

    //定义打包的过程
    public abstract void packager();

    //定义安装的过程
    public abstract void install();
}

模拟 clean 插件的子类,代码如下。

/**
* 子类模拟clean 相关的插件
*/
public abstract class CleanPlugin extends LifeCycle {
    
    
    //重写父类(生命周期)的清理工作
    //模拟插件目标
    @Override
    public void clean() {
    
    
        System.out.println("清理");
    }
}

以上示例中,父类 LifeCycle 模拟的是 Maven 生命周期,子类 CleanPlugin 模拟的是 Maven 插件,而子类中重写的 clean() 模拟的是插件目标。插件的本意就是插拔式的,用了添加不用不添加。

虽然示例中的代码与 Maven 实际代码相去甚远,但它们的基本理念是方法相同的。生命周期抽象了构建的各个步骤,定义了它们的执行顺序,但却没有提供具体的实现。插件中完成了对构建过程的实现,想要完成某个构建步骤,调用插件中的一个或多个插件目标即可。

2、maven的三套生命周期

Maven 的生命周期并非只有一套,而是有三套,并且这三套生命周期之间是没有关系的。一套生命周期包含很多个不同的阶段,这些不同的阶段是有顺序的,有些阶段必须要在某个阶段完成之后,才能进行。Maven 的三套生命周期分别为:clean(清理),default(默认),site(站点)。接下来我们就一一介绍一下这三个生命周期。

clean:用于清理项目,clean 生命周期包括以下 3 个阶段:

  1. pre-clean: 清理前的准备工作;
  2. clean:清理上一次构建的结果;
  3. post-clean:清理结束后需要完成的工作。

default:default 生命周期定义了项目真正构建时所需要的所有步骤,它是所有生命周期中最核心,最重要的部分。

default 生命周期包含非常多的阶段,如下表:

site:sit 生命周期的目的是建立和部署项目站点,Maven 能够根据 POM 包含的信息,自动生成一个友好的站点,该站点包含一些与该项目相关的文档。

site 生命周期包含以下 4 个阶段:

  1. pre-site:准备阶段。在生成站点前所需要做的工作;
  2. site:生成站点阶段;
  3. post-site:结束阶段。生成站点结束后所需要做的工作;
  4. site-deploy:发布阶段。我们可以将上面生成的站点发布到对应服务器中。

3、生命周期执行规则

每套生命周期包含一系列的构建阶段(phase),这些阶段是有顺序的,且后面的阶段依赖于前面的阶段。用户与 Maven 最直接的交互方式就是调用这些生命周期阶段。

以 clean 生命周期为例,它包含 pre-clean、clean 以及 post-clean 三个阶段,当用户调用 pre-clean 阶段时,则只有 pre-clean 阶段执行;当用户调用 clean 阶段时,pre-clean 和 clean 阶段都会执行。当用户调用 post-clean 阶段时,则 pre-clean、clean 以及 post-clean 三个阶段都会执行。

三套生命周期本身是相互独立的,用户可以只调用 clean 生命周期的某个阶段,也可以只调用 default 生命周期的某个阶段,而不会对其他生命周期造成任何影响。当然也可以同时调用两套生命周期的某个阶段。

通过将阶段名传递给 mvn 命令,就可以调用构建阶段,例如:
mvn clean,就是调用clean生命周期的clean阶段,当前项目的target目录会被清空。

我们试着执行 Maven 的打包命令:mvn package -DskipTests(-DskipTests是跳过测试的意思,假如不跳过测试,他在打包的时候会自动执行项目test目录下带有@Test注解的方法)。就是调用default生命周期的package 阶段,执行完成之后,可以看到其所经过的生命周期。因此,当我们想要构建项目的时候,并不需要分别执行 package 阶段之前的阶段,而是 Maven 自动为我们执行。突然发现,原来构建项目是如此的简单,方便。

生命周期中的每个构建过程都可以绑定一个或多个插件目标,且 Maven 为大多数的构建步骤都绑定了默认的插件。例如,针对源代码编译的插件是 maven-compiler-plugin、针对集成测试的插件是 maven-surefire-plugin 等(关于这一点后面会细说)。

同时我们也可以执行两套生命周期,例如调用clean生命周期的clean阶段再加上default生命周期的package阶段:mvn clean package -DskipTests

二、Maven插件(plugin)

1、两种类型的插件

Maven 实际上是一个依赖插件执行的框架,它执行的每个任务实际上都由插件完成的。使用Maven打出来的包并不包含任何 Maven 插件,它们以独立构件的形式存在, 只有在 Maven 需要使用某个插件时,才会去仓库中下载。

如下表所示,Maven 提供了如下 2 种类型的插件:

2、调用插件有两种方式

插件目标: 对于 Maven 插件而言,为了提高代码的复用性,通常一个 Maven 插件能够实现多个功能,每一个功能都是一个插件目标,即 Maven 插件是插件目标的集合。我们可以把插件理解为一个类,而插件目标是类中的方法,调用插件目标就能实现对应的功能。

使用的两种方式:

  1. 引入到项目当中,然后将插件绑定到指定的生命周期,然后执行声明周期命令会自动调用该插件,例如:mvn clean、mvn install
  2. 通过如下命令可以直接调用插件。
    • 使用 Maven 命令执行插件的目标,语法如:mvn [插件名]:[目标名]
    • 例如,调用 maven-compiler-plugin 插件的 compile 目标,命令如:mvn compiler:compile(注意不能使用插件的全名,一定是缩写名,不然会报找不到插件)

插件绑定: 为了完成某个具体的构建任务,Maven 生命周期的阶段需要和 Maven 插件的目标相互绑定。例如,代码编译任务对应了default 生命周期的 compile 阶段,而 maven-compiler-plugin 插件的 compile 目标能够完成这个任务,因此将它们进行绑定就能达到代码编译的目的。

3、内置绑定

Maven 默认为一些核心的生命周期阶段绑定了插件目标,当用户调用这些阶段时,对应的插件目标就会自动执行相应的任务。

表中,default 生命周期中只列出了绑定了插件目标的阶段,它还有很多其他的阶段,但这些阶段默认没有绑定任何插件目标,因此它们也没有任何实际的行为。

在这里插入图片描述

我们可以直接在执行 Maven 命令看到该构建过程包含了哪些插件目标。例如,在 Maven 项目中执行 mvn clean install 命令,能看到如下输出,图中标记的部分就是执行此命令时所调用的插件目标。

像这些内置绑定的插件我们也可以在项目当中去显示的声明然后修改配置,这时候内置绑定插件的默认配置将会被覆盖!

4、自定义绑定插件

除了内置绑定之外,用户也可以自己选择将某个插件目标绑定到 Maven 生命周期的某个阶段上,这种绑定方式就是自定义绑定。自定义绑定能够让 Maven 在构建过程中执行更多更丰富的任务。

例如,我们想要在 clean 生命周期的 clean 阶段中显示自定义文本信息,则只需要在项目的 POM 中 ,通过 build 元素的子元素 plugins,将 maven-antrun-plugin插件的run 目标绑定到 clean 阶段上,并使用该插件输出自定义文本信息即可。

<build>
	<plugins>
        <!-- 绑定插件 maven-antrun-plugin -->
        <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-antrun-plugin</artifactId>
              <version>3.0.0</version>
              <executions>
                  <execution>
                    <!--自定义 id -->
                    <id>custom clean</id>
                    <!--插件目标绑定的构建阶段 -->
                    <phase>clean</phase>
                    <!--插件目标 -->
                    <goals>
                    	<goal>run</goal>
                    </goals>
                    <!--配置 -->
                    <configuration>
                      	<!-- 执行的任务 -->
                    	<target>
                        	<!--自定义文本信息 -->
                        	<echo message="清理阶段"/>
                      </target>
                    </configuration>
                  </execution>
              </executions>
          </plugin>
	</plugins>
</build>

以上配置中除了插件的坐标信息之外,还通过 executions 元素定义了一些执行配置。executions 下的每一个 executin 子元素都可以用来配置执行一个任务。execution 下各个元素含义如下:

  • id:任务的唯一标识。
  • phase:插件目标需要绑定的生命周期阶段。
  • goals:用于指定一组插件目标,其子元素 goal 用于指定一个插件目标。
  • configuration:该任务的配置,其子元素 tasks 用于指定该插件目标执行的任务。

执行命令 mvn clean ,结果如下:

以上我们只是简单使用maven-antrun-plugin插件的run目标绑定到了clean阶段打印了一段文字,实际我们还可以通过该插件来完成一些特殊工作,例如打包过后自动将包上传到指定位置等等…这里就不细说了。

插件的运行顺序: 当插件目标绑定到生命周期的不同阶段时,其执行顺序由生命周期阶段的先后顺序决定。如果多个目标绑定到同一个生命周期阶段,其执行顺序与插件声明顺序一致,先声明的先执行,后声明的后执行。

三、官网查找插件

官网:https://maven.apache.org/plugins/index.html

这里就拿maven-antrun-plugin插件来说,首先打开官网然后搜索antrun,如下:

点击antrun进来以后看到如下:

点击目标进来以后可以看到该插件可配置的标签:

注意:光看标签有时候根本不知道怎么用,尽量配合着用法示例来使用。

点击Using <target/> Attributes用法示例如下:

并不是所有的插件都是maven开发的,还有一些其他公司进行开发的,如下:

猜你喜欢

转载自blog.csdn.net/weixin_43888891/article/details/130756192