IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Maven温故知新-生命周期与插件 -> 正文阅读

[Java知识库]Maven温故知新-生命周期与插件


前言

??maven大家都很熟悉,平时在开发中我们用它来管理项目结构、引入依赖以及项目构建,在开发完成之后也可有用它来打包并将制品发布到私服,也可以根据选择进行站点发布以版本发布(release),maven虽然并不能在代码层面给予帮助,但是它却能做一些最一些其他很酷的事,所以熟练的掌握maven也是至关重要的。

??最近在工作中遇到了maven相关问题,发现对maven的认识有一些偏差,于是又重新研究了一下关于生命周期、插件以及profile的相关内容,收获颇多,特此记录。


??我们平时会使用到一些指令,如mvn clean,但很有可能仅仅停留在知道这些指令能做什么,但并不了解背后的原理,在工作中如要对修改项目maven配置,或者自己开发一些插件就不知道怎么办了。这些指令涉及到的知识点主要有两个:生命周期以及插件,本文主要介绍他们的部分精华内容。

一、生命周期

??maven的生命周期共有三个,分别是cleandefault以及site,每个生命周期由不同的phase(阶段)构成,而每个phase按照约定又都是按照固定顺序执行的

clean

??该生命周期主要负责处理项目的清理,共有三个phase,按照顺序分别如下:

  • pre-clean
  • clean:执行清理操作,删除上一次构建生成的文件。
  • post-clean

pre的意思为在…之前执行,post为在…之后执行,其他周期类似的也为同样的概念。

default

??该生命周期主要构建操作,如编译、打包、部署等,包含的phase共23个,常用的按照顺序分别如下:(完整phase见这里)

  • compile:编译项目源文件。
  • test-compile:编译项目测试源文件。
  • test:执行单元测试。
  • package:将编译后的文件按照指定的形式打包,如jarwar等,其中不包含测试文件。
  • install:将打包后的制品安装到本地仓库,可供本地其他项目使用。
  • deploy:将打包后的制品发布到指定远程仓库,可供其他项目使用。

site

??该生命周期主要负责站点的创建。共有四个phase,按照顺序分别如下:

  • pre-site
  • site:在本地生成站点文档。
  • post-site
  • site-deploy:将生成的站点文档部署到指定服务器。

??执行同一个生命周期的phase会按照顺序先执行排在它之前的其他phase,如执行default周期中的package,会自动按照顺序执行compiletest-compiletest等,如果都顺利执行成功,那么最后才会执行package,所以平时在执行指令时,同一周期的phase不需要依次指定,只需要执行排在最后边的周期即可。

??所有的生命周期定义以及顺序,都在maven源码中maven-core/src/main/resources/META-INF/plexus/components.xml中。

在这里插入图片描述


??以上我们又重新的回顾了一遍生命周期以及phase,其中phase并不会真正的做一些工作,真正执行工作的是插件(plugin)。

二、插件与goal

plugin(插件)

Maven is - at its heart - a plugin execution framework; all work is done by plugins.

??如同上述官方文档中描述的一样,maven可以看作是一个插件执行框架,因为maven中所有的工作都是由插件来完成的。我们平时执行的指令最终也都是执行对应的插件,如mvn clean,最终的工作是由maven-clean-plugin插件来完成的。

??插件的本质也都是jar,如同项目中引用的其他依赖一样,插件的坐标也与普通坐标相同,如org.apache.maven.plugins:maven-clean:plugin:3.1.0maven的官方插件都在本地仓库的org/apache/maven/plugins下。
在这里插入图片描述
??下图为maven-clean-plugin插件源代码截图:
在这里插入图片描述

插件的默认版本

??不通版本的maven中插件的默认版本也不同,会在maven源码中进行指定,其中cleansite生命周期的插件定义在maven-core/src/main/resources/META-INF/plexus/components.xml中;而default生命周期的插件,由于package选项的不同可能对应不同的插件,它定义在maven-core/src/main/resources/META-INF/default-bindings.xmll中。

??如maven-3.8.4中指定的maven-clean-plugin版本为2.5.0而不是最新的3.1.0,如下图所示:
在这里插入图片描述
在这里插入图片描述

在项目中配置插件

??不同与普通依赖的引用,项目中插件的引用在pom.xml中是通过<build>下的<plugin>中进行配置的,可以配置插件的版本、参数以及一些其他相关配置。

??如通过IDEA创建maven项目时,如选择选择create from archetype,那么生成的pom.xml可能如下,该配置主要指定了插件版本:
在这里插入图片描述

??可以看出执行clean指令p<m时不再使用默认的maven-cliean-plugin:2.5.0,而改为使用配置的maven-clean-plugin:3.1.0了。

插件的前缀(prefix)

??插件的坐标有时候会经常出现在命令行中,如果输入完整坐标,那会显得太过冗长,如:

mvn org.apache.maven.plugins:maven-clean-plugin:3.1.0:clean

??为了方便使用,maven提供了前缀的概念,分为自动识别以及手动指定

自动识别

??如果插件的artifactId符合以下模式,那么maven会自动识别,将该插件与插件进行映射:

  • maven官方插件:maven-${prefix}-plugin。(此命名规则为maven官方插件预留,自定义插件禁止使用)
  • 第三方/自定义:${prefix}-maven-plugin

??如官方插件apache-clean-pluginapache-compile-plugin等,我们就可以直接使用cleancompile,而不需要指定冗长的坐标。

??再如有自定义插件hello-maven-plugin,那么则可以使用hello来方便使用该插件。

手动指定

??手动识别是针对我们自己开发的插件,可以通过配置去指定该插件的前缀。由于本文的内容不是介绍自定义插件的开发,固只列出相关前缀的配置
在这里插入图片描述
??通过如上配置,在使用时就可以使用myPrefix来替代坐标了。


goal(目标)

??一个插件可以拥有若干个goal(目标),这些goal对于插件来说,就好像方法于类。

直接调用goal

??调用的语法为:

mvn PLUGIN:GOAL

??如常用的mvn release:preparemvn dependency:analyze等,此时就会直接执行release插件中名为preparegoal来执行任务。

绑定goal至phase

??除了可以直接调用外,goal也可以绑定在一个或多个phase上。如若此,则执行到该phase时会执行该goal

??而相对于phase来说,如果该phase未绑定goal,那么该phase不会执行。如果绑定了一个或多个goal,那么就会按照顺序依次执行他们。

内置的goal与phase的绑定

??maven内置了一些goal的绑定,也就是这些goal会内置的绑定在某个phase上,我们在执行phase的时候也就会自动执行这些goal,一些常用的绑定关系如下:

  • clean
phasegoal
cleanclean:clean
  • default
phasegoal
compilecompile:compile
test-compilecompile:testCompile
packageejb:ejb or ejb3:ejb3 or jar:jar or par:par or rar:rar or war:war
installinstall:install
deploydeploy:deploy
  • site
phasegoal
sitesite:site
site-deploysite:deploy

??内置goal的绑定同上述的插件一起定义在源码中的maven-core/src/main/resources/META-INF/plexus/components.xml以及maven-core/src/main/resources/META-INF/plexus/default-bindings.xml中,这也就是为什么项目中可能没有配置如maven-clean-pluginmaven-compile-plugin等插件,在执行指令时依旧可以正常执行的原因。

??前文说过,如果phase没有绑定goal那么该phase不会执行,再由上面的默认绑定关系可知,诸如pre-clean以及post-cleanphase默认情况下不会执行,因为没有绑定goal。这些phase可有理解为预留,可以根据需要在pom中去配置相应绑定的goal,来达到在某行为之前或之后执行我们的目标任务。

手动指定需要绑定的phase

??在声明的<plugin><executions>标签下进行插件的具体配置,可能如下所示:

<build>
 <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-antrun-plugin</artifactId>
      <version>1.8</version>
      <executions>
        <execution>
          <id>manifest</id>
          <phase>generate-resources</phase>
          <goals>
            <goal>run</goal>
          </goals>
          <configuration>
            <tasks>
              <manifest file="src/main/resources/META-INF/MANIFEST.MF">
                <attribute name="Project-Version" value="${project.version}" />
                <attribute name="Application-Name" value="My Application" />
              </manifest>
            </tasks>
          </configuration>
        </execution>
      </executions>
    </plugin>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-javadoc-plugin</artifactId>
      <version>3.2.0</version>
      <executions>
        <execution>
          <phase>prepare-package</phase>
          <goals>
            <goal>javadoc</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

??上述配置了两个插件,antrun以及javadoc(插播复习一个小知识:插件的前缀),想要执行的工作很简单,antrun负责生成MANIFEST.MF清单文件,并配置了生成的内容以及路径等;javadoc负责生成java文档。
??其中还有一部分配置将phase以及goal绑定了起来

<execution>
  <!-- 绑定到哪个phase中 -->
  <phase>...</phase>
  <goals>
    <!-- 执行该插件的哪个goal,可指定多个 -->
    <goal>...</goal>
    <goal>...</goal>
  </goals>
<execution>

??也就是说,当mvn执行generate-resources阶段时会调用antrun:run,而当执行prepare-package阶段时会调用javadoc:javadoc,如执行指令mvn compile,像上文章讲解的一样,会优先执行compile顺序之前的phase,其中就包含generate-resources,执行到该phase时就会调用绑定的antrn:run目标了。

在这里插入图片描述

??再如执行mvn package指令,会优先执行generate-resources,之后在执行prepare-package,并执行绑定的goal
在这里插入图片描述
??这样一来我们在平时的编译、打包、部署等操作时,就能自动的执行一些我们想要的任务,而不需要我们手动去执行他们,可以极大程度的提高构建易用性与速度,一般实际的项目都会广泛的采用这种方式。

查看插件拥有的goal

??那么怎么样知道一个插件拥有哪些goal

  1. 如果是maven官方插件,可以查看maven官网,之后点击插件名,就可以看到具体的goal有哪些了,还会有参数说明以及使用demo。 在这里插入图片描述
  2. mojohaus也收录了一些第三方插件
  3. 在本地可以调用help:describe来查看某一插件的具体情况,如
# mvn help:describe -Dplugin=apache.javadoc.plugin
mvn help:describe -Dplugin=javadoc

在这里插入图片描述


跳过goal

??有些情况下我们在执行某phase时不想执行某些goal,那么需要查看该goal是否提供相应参数。如我们想在执行package的时候跳过test单元测试,那么我们需要查看test绑定的goalsurefile:test是否有可以跳过的参数。文档中表示,可以-Dmaven.test.skip=true-DskipTests来跳过单元测试,区别是前者即跳过测试又不编译测试文件,而后者只是跳过,但是会编译测试文件。

??所以这里maven.test.skiptest指的其实并不是插件,而是参数名称为maven.test.skip。类似的还有如跳过compile插件需要使用参数-Dmaven.main.skip=true来设置,具体其他的goal需要查看官方文档。

??也可以在pom.xml中配置,这样就不用再输入指令时加参数了,会自动添加配置的参数,如下所示:
在这里插入图片描述

??需要注意的是,跳过的永远是goal, 而不是phase。如同上文描述,一个phase可能绑定很多goal,跳过一个不代表所有的都跳过。

三、父子多模块的相关执行顺序

??父子多模块项目,如一个父项目parent以及三个子模块childAchildB以及childC,在执行phase时,有两个顺序需要明确:

  • 模块执行顺序

??模块的执行顺序由以下两部分决定:

??1. 基础顺序,即在父pom中声明模块的顺序,如我们在pom.xml中配置如下

 <modules>
    <module>moduleA</module>
    <module>moduleB</module>
    <module>moduleC</module>
</modules>

??
在这里插入图片描述
??可以看到在执行指令时,最优先执行是模块,其次会按照pom.xml中指定的模块顺序执行。

??2. 在基础顺序之上的依赖关系。假设moduleA依赖moduleB,我们还按照上例声明的模块顺序进行试验,配置情况以及结果如下:

<artifactId>moduleA</artifactId>
  
<dependencies>
  <dependency>
    <groupId>${project.groupId}</groupId>
    <artifactId>moduleB</artifactId>
    <version>${project.version}</version>
  </dependency>
</dependencies>

在这里插入图片描述

??可有看到最终的结果是B A C,也比较合理,比如打包等,不先把依赖的包编译好,可能就会有问题。

  • 模块phase的执行顺序

??一个模块的所有phase执行完之后,才会继续执行下一个模块的phase,而不是执行所有模块的一个phase,再执行所有模块的下个phase,理解这点对于平时项目的构建是十分必要的。其流程如下图所示:
在这里插入图片描述

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-02-03 01:03:47  更:2022-02-03 01:04:18 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 10:55:20-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码