Maven实战.插件

news2024/9/17 9:14:35

文章目录

  • 插件目标
  • 插件绑定
    • 内置绑定
    • 自定义绑定
  • 插件配置
    • 命令行插件配置
    • POM中插件全局配置
    • POM中插件任务配置

插件目标

在进一步详述插件和生命周期的绑定关系之前,必须先了解插件目标(PluginCoal)的概念。我们知道,Maven 的核心仅仅定义了抽象的生命周期具体的任务是交由插件完成的,插件以独立的构件形式存在,因此,Maven 核心的分发包只有不到3MB的大小,Maven 会在需要的时候下载并使用插件。

对于插件本身,为了能够复用代码,它往往能够完成多个任务。例如maven-dependency-plugin,它能够基于项目依赖做很多事情。它能够分析项目依赖,帮助找出潜在的无用依赖;它能够列出项目的依赖树,帮助分析依赖来源;它能够列出项目所有已解析的依赖等等。为每个这样的功能编写一个独立的插件显然是不可取的,因为这些任务背后有很多可以复用的代码,因此,这些功能聚集在一个插件里,每个功能就是一个插件目标。

maven-dependency-plugin 有十多个目标,每个目标对应了一个功能,上述提到的几个功能分别对应的插件目标为dependency : analyze、dependency : tree 和 dependency : list。这是一种通用的写法,冒号前面是插件前缀,冒号后面是该插件的目标。类似地,还可以写出compiler : compile(这是 maven-compiler-plugin 的 compile 目标)和surefire : test(这是 maven-sure-fire-plugin 的 test 目标)。

插件绑定

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

内置绑定

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

clean 生命周期仅有 pre-clean、clean 和 post-clean 三个阶段,其中的clean 与 maven-clean-plugin : clean 绑定。maven-clean-plugin 仅有clean 这一个目标,其作用就是删除项目的输出目录。clean 生命周期阶段与插件目标的绑定关系如下图所示。
在这里插入图片描述

site 生命周期有 pre-site、site、post-site 和 site-deploy 四个阶段,其中,site 和 maven-siteplugin : site 相互绑定,site-deploy 和 maven-site-plugin : depoy相互绑定。maven-site-plugin 有很多目标,其中,site 目标用来生成项目站点,deploy 目标用来将项目站点部署到远程服务器上。site 生命周期阶段与插件目标的绑定关系如下图所示。
在这里插入图片描述
相对于 clean 和 site 生命周期来说,default 生命周期与插件目标的绑定关系就显得复杂一些。这是因为对于任何项目来说,例如 jar 项目和 war 项目,它们的项目清理和站点生成任务是一样的,不过构建过程会有区别。例如 jar 项目需要打成 JAR 包,而 war 项目需要打成 WAR 包。

由于项目的打包类型会影响构建的具体过程,因此,defaut 生命周期的阶段与插件目标的绑定关系由项目打包类型所决定,打包类型是通过 POM 中的 packaging 元素定义的。最常见、最重要的打包类型是 jar,它也是默认的打包类型。基于该打包类型的项目,其 default 生命周期的内置插件绑定关系及具体任务如下图所示。
在这里插入图片描述
注意,上图只列出了拥有插件绑定关系的阶段,default 生命周期还有很多其他阶段,默认它们没有绑定任何插件,因此也没有任何实际行为。

除了默认的打包类型 jar 之外,常见的打包类型还有 war、pom、maven-plugin、ear 等。它们的 defaut 生命周期与插件目标的绑定关系可参阅 Maven 官方文档,这里不再赘述。

你也可以从 Maven 项目的命令行执行 mvn clean install 命令,看到项目在构建过程中执行了哪些插件目标。

自定义绑定

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

一个常见的例子是创建项目的源码 jar 包,内置的插件绑定关系中并没有涉及这一任务,因此需要用户自行配置。maven-source-plugin 可以帮助我们完成该任务,它的 jar-no-fork 目标能够将项目的主代码打包成iar 文件,可以将其绑定到 default 生命周期的 verify 阶段上、在执行完集成测试后和安装构件之前创建源码 jar 包。具体配置见如下代码:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-source-plugin</artifactId>
    <version>2.2.1</version>
    <executions>
        <execution>
            <id>attach-sources</id>
            <phase>verify</phase>
            <goals>
                <goal>jar-no-fork</goal>
            </goals>
        </execution>
    </executions>
</plugin>

在 POM 的 build 元素下的 plugins 子元素中声明插件的使用,该例中用到的是 maven-scurce-plugin,其 groupId 为org:apache.maven.plugins,这也是 Maven 官方插件的 groupId,紧接着 artifactld 为 maven-source-plugin,version 为 2.2.1。对于自定义绑定的插件,用户总是应该声明一个非快照版本,这样可以避免由于插件版本变化造成的构建不稳定性。

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

[INFO] --- source:2.2.1:jar-no-fork (attach-sources) @ hello-world ---
[INFO] Building jar: D:\Work\gittest\demo-maven-practical\hello-world\target\hello-world-1.0-SNAPSHOT-sources.jar

我们可以看到,当执行 verify 生命周期阶段的时候,maven-source-plugin:jar-no-fork 会得以执行,它会创建一个以“ -sources.jar”结尾的源码文件包。

有时候,即使不通过 phase 元素配置生命周期阶段,插件目标也能够绑定到生命周期中去。例如,可以尝试删除上述配置中的 phase 一行,再次执行mvn verify,仍然可以看到 maven-source-plugin:jar-no-fork 得以执行。出现这种现象的原因是:有很多插件的目标在编写时已经定义了默认绑定阶段。可以使用 maven-help-plugin 查看插件详细信息,了解插件目标的默认绑定阶段。运行命令如下:

mvn help:describe -Dplugin=org.apache.maven.plugins:maven-source-plugin:3.2.1 -Ddetail

该命令输出对应插件的详细信息。在输出信息中,能够看到关于目标 jar-no-fork 的如下信息:

...
source:jar-no-fork
  Description: This goal bundles all the sources into a jar archive. This
    goal functions the same as the jar goal but does not fork the build and is
    suitable for attaching to the build lifecycle.
  Implementation: org.apache.maven.plugin.source.SourceJarNoForkMojo
  Language: java
  Bound to phase: package

  Available parameters:
...

该输出包含了一段关于 jar-no-fork 目标的描述,这里关心的是 Bound to phase 这一项,它表示该目标默认绑定的生命周期阶段(这里是package)。也就是说,当用户配置使用 maven-source-plugin 的 jar-no-fork 目标的时候,如果不指定 phase 参数,该目标就会被绑定到 package Maven 生命周期 default周期 的 package 阶段。

当插件目标被绑定到不同的生命周期阶段的时候,其执行顺序会由生命周期阶段的先后顺序决定。如果多个目标被绑定到同一个阶段,它们的执行顺序会是怎样?答案很简单,当多个插件目标绑定到同一个阶段的时候,这些插件声明的先后顺序决定了目标的执行顺序。

插件配置

完成了插件和生命周期的绑定之后,用户还可以配置插件目标的参数,进一步调整插件目标所执行的任务,以满足项目的需求。几乎所有 Maven 插件的目标都有一些可配置的参数,用户可以通过命令行和 POM 配置等方式来配置这些参数。

命令行插件配置

在日常的 Maven 使用中,我们会经常从命令行输入并执行 Maven 命令。在这种情况下如果能够方便地更改某些插件的行为,无疑会十分方便。很多插件目标的参数都支持从命令行配置,用户可以在 Maven 命令中使用 -D 参数,并伴随一个参数键=参数值的形式,来配置插件目标的参数。

例如,maven-surefire-plugin 提供了一个 maven.test.skip 参数,当其值为 true 的时候,就会跳过执行测试。于是,在运行命令的时候,加上如下 -D 参数就能跳过测试:

 mvn install -Dmaven.test.skip=true

参数- D 是 Java 自带的,其功能是通过命令行设置一个 Java 系统属性,Maven 简单地重用了该参数,在准备插件的时候检查系统属性,便实现了插件参数的配置。

POM中插件全局配置

并不是所有的插件参数都适合从命令行配置,有些参数的值从项目创建到项目发布都不会改变,或者说很少改变,对于这种情况,在 POM 文件中一次性配置就显然比重复在命令行输入要方便。

用户可以在声明插件的时候,对此插件进行一个全局的配置。也就是说,所有该基于该插件目标的任务,都会使用这些配置。例如,我们通常会需要配置 maven-compiler-plugin 告诉它编译 Java 1.5 版本的源文件,生成与 JVM1.5 兼容的字节码文件,见代码如下:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <source>1.5</source>
        <target>1.5</target>
    </configuration>
</plugin>

这样,不管绑定到 compile 阶段的 maven-compiler-plugin:compie 任务,还是绑定到 test-compiler 阶段的 maven-compiler-plugin:testCompiler 任务,就都能够使用该配置,基于Java1.5 版本进行编译。

插件全局配置元素是 configuration 元素。

POM中插件任务配置

除了为插件配置全局的参数,用户还可以为某个插件任务配置特定的参数。以 maven-antrumn-plugin 为例,它有一个目标 run,可以用来在 Maven 中调用 Ant 任务。用户将 maven-antrun-plugin:run 绑定到多个生命周期阶段上,再加以不同的配置,就可以让 Maven 在不同的生命阶段执行不同的任务,如下:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-antrun-plugin</artifactId>
    <version>1.8</version>
    <executions>
        <execution>
            <id>ant-validate</id>
            <phase>validate</phase>
            <goals>
                <goal>run</goal>
            </goals>
            <configuration>
                <tasks>
                    <echo>i am bound to validate phase</echo>
                </tasks>
            </configuration>
        </execution>
        <execution>
            <id>ant-verify</id>
            <phase>verify</phase>
            <goals>
                <goal>run</goal>
            </goals>
            <configuration>
                <tasks>
                    <echo>i am bound to verify phase</echo>
                </tasks>
            </configuration>
        </execution>
    </executions>
</plugin>

在上述代码片段中,首先,maven-antrun-plugin:run 与 validate 阶段绑定,从而构成一个 id 为 ant-validate 的任务。插件全局配置中的 configuration 元素位于 plugin 元素下面,而这里的 confguration 元素则位于 execution 元素下,表示这是特定任务的配置,而非插件整体的配置。这个 ant-validate 任务配置了一个echo Ant 任务,向命令行输出一段文字,表示该任务是绑定到 validate 阶段的。第二个任务的 id 为 ant-verify,它绑定到了 verify 阶段,同样它也输出一段文字到命令行,告诉该任务绑定到了verify 阶段。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1963464.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

外星人入侵_计分

外星人入侵_计分 1添加Play按钮1.1创建Button类1.2在屏幕上绘制按钮1.3开始游戏1.4 重置游戏1.5 将Play按钮切换到非活动状态1.6隐藏光标 2提高等级2.1修改速度设置2.2重置速度 3计分3.1显示得分3.2创建记分牌3.3在外星人被消灭时更新得分3.4将消灭的每个外星人的点数都计入得分…

Linux:shell命令

Linux&#xff1a;shell命令 Shell echo命令 显示普通字符串 echo "i am wsf"显示转义字符 echo "i\" am usf"显示变量 read name#相当于python中的input echo "${name} is a name"read -p "请输入您的名字&#xff1a;" names#提…

怎么用U盘重装系统

在使用电脑的过程中&#xff0c;难免会遇到系统故障、运行缓慢等问题。当这些问题严重影响使用电脑的体验时&#xff0c;重装系统往往是一个有效的解决办法。用U盘重装系统是一种简单快捷的方法&#xff0c;本文将详细介绍如何使用U盘来重装系统&#xff0c;帮助大家轻松完成这…

推荐|代码签名证书怎么选?EV还是OV?

代码签名证书支持给.exe&#xff0c;.cab&#xff0c;.dll&#xff0c;.ocx&#xff0c;.msi&#xff0c;.xpi&#xff0c;.xap 等软件、控件进行数字签名!在选择代码签名证书时&#xff0c;EV和OV是两种常见的选择。这两种证书都用于对软件或应用程序进行数字签名。应该如何选…

在线短剧APP开发,短剧市场的新赛道新盈利

近几年中&#xff0c;短剧行业规模飞速上涨&#xff0c;越来越多的入局者开始进入市场&#xff0c;随着短剧市场的不断升温&#xff0c;也衍生出了短剧APP&#xff0c;为行业的发展带来了新的赛道&#xff01; 短剧APP的出现为观众提供了一个专属的短剧“港湾”&#xff0c;让…

探索智慧园区的创新实践与未来展望

智慧园区是指运用物联网、大数据、云计算、人工智能等新一代信息技术&#xff0c;对园区进行全方位、全时段的智能化改造&#xff0c;实现管理高效、服务便捷、环境友好、创新驱动的现代化园区形态。其核心理念在于通过技术赋能&#xff0c;优化资源配置&#xff0c;提升园区运…

基于MT76X8平台的Mtk-openwrt-sdk配置单网口方法

一、配置. 在SDK的工程下&#xff0c;运行make kernel_menuconfig&#xff0c;如下图所示&#xff1a; Ralink Module --->选上“One Port Only”&#xff0c;如下图所示&#xff1a; 如果P0网口实现WAN口&#xff0c;就配置成W/LLLL,否则就配置成LLLL/W. 二、修改网口的…

Camera Raw 修图简明教程

Adobe Camera Raw&#xff08;简称为 ACR &#xff09;是 Adobe 开发的一款强大插件&#xff0c;专为处理和编辑相机原始文件&#xff08;Raw 格式&#xff09;而设计&#xff0c;旨在帮助摄影师和图像编辑人员实现高质量的转码和图像处理。 如果想用 Camera Raw 处理 JPEG、TI…

使用C++和Mysql进行图像存取操作记录

使用C和Mysql进行图像存取操作记录 配置&#xff1a; 1.Mysql 5.5.19 2.Vs2019 3.C 一、创建图像存储表格 选择数据库指令&#xff1a; 将databasename改成你想操作的数据库就行。我这边依旧在student_manager数据库下进行操作。 use databasename;CREATE TABLE images(im…

知迪动态丨北斗智联领导团队莅临知迪科技上海研发中心

7月29日&#xff0c;北斗智联领导团队来到知迪科技参观考察。知迪科技总裁周强先生率公司管理层与技术代表热情接待。 北斗智联一行在知迪科技公司团队的陪同下&#xff0c;首先观摩了在技术展示区陈列的车辆数据记录设备、总线信号分析及仿真设备、ADAS HiL测试台架、测试自动…

【PostGresql】---- pgSql 将列中合并字符串拆分为多行 实例代码

-- 将 AQY_ID,AQY 中的字符串拆分为多行 SELECT"ID","AQY_ID","AQY",UNNEST ( string_to_array( "AQY_ID", , ) ) AS "AQY_ID_1",UNNEST ( string_to_array( "AQY", , ) ) AS "AQY_1" FROM"JF_SGC…

科目一考试题库(超全)!7分钟一把过科目一(总结经验)

1、先看视频 先了解考试规范、流程以及重要的考点难点&#xff0c;做到心中有数&#xff0c;大部分人觉得重难点在扣分题和罚款题上面&#xff0c;可以在网上看一些视频讲解&#xff0c;1.5倍速快速过一遍看的过程中记录一些笔记&#xff0c;可以随便看的而且真滴有用 2、认真刷…

教你如何从Flink小白成为Contributor最终拿到腾讯的Offer

简言&#xff1a;一开始我也是怀揣着成为一个技术大老的梦想开始的&#xff0c;尽管我现在已经入职腾讯三年多了有时候觉得自己还是一个菜鸡哈..... 写这个文章希望可以帮助到刚刚接触大数据&#xff0c;并且对技术怀揣着梦想的朋友们&#xff0c;大家互相学习哈(对Flink不是很…

成都云飞浩容文化传媒有限公司领航电商新纪元

在数字经济浪潮汹涌的今天&#xff0c;电商行业作为时代的弄潮儿&#xff0c;正以前所未有的速度改变着商业版图。成都&#xff0c;这座历史悠久而又充满活力的城市&#xff0c;正孕育着一家在电商服务领域独树一帜的企业——成都云飞浩容文化传媒有限公司。作为一家深耕电商服…

Linux系统编程(4):消息队列

Linux下的进程通信手段基本上是从Unix平台上的进程通信手段继承而来的。 而对Unix发展做出重大贡献的两大主力AT&T的贝尔实验室 以及 BSD&#xff08;加州大学伯克利分校的伯克利软件发布中心&#xff09;&#xff0c; 他们在进程间通信方面的侧重点有所不同&#xff1b; 前…

歌唱比赛活动策划方案书

&#xff08;一&#xff09;海选 1、时间&#xff1a;12月16日 2、地点&#xff1a;公司食堂 3、比赛评委设置&#xff1a;共计6名评委。 4、比赛规则&#xff1a; &#xff08;1&#xff09;选手按报名顺序及上报歌曲进行清唱&#xff08;限时2分钟&#xff0c;类型…

时间序列分析方法之 -- 指数平滑(Exponential Smoothing)原理及Python代码示例

目录 原理 适用情况 Python 示例代码 结论 原理 指数平滑&#xff08;Exponential Smoothing&#xff09;是一种用于时间序列分析和预测的平滑技术。与简单移动平均&#xff08;SMA&#xff09;和加权移动平均&#xff08;WMA&#xff09;不同&#xff0c;指数平滑通过对最…

手势传感器 - 从零开始认识各种传感器【第十八期】

手势传感器|从零开始认识各种传感器 1、什么是手势传感器 手势传感器是一种能够感知人类手势或动作的传感器。它可以捕捉、识别和解释人类的手部动作或姿势&#xff0c;并将其转换成电信号或数字信号&#xff0c;通过识别人体的手势动作来实现与电子设备的交互&#xff0c;如控…

Traefik系列

一、入门Traefik系列——基础简介 官方文档 https://doc.traefik.io/traefik/[1] 简介 Traefik是一个为了让部署微服务更加便捷而诞生的现代HTTP反向代理、负载均衡工具。它支持多种后台 (Docker, Swarm, Kubernetes, Marathon, Mesos, Consul, Etcd, Zookeeper, BoltDB, Re…