Maven插件开发及Demo演示

news2024/11/26 17:50:19

引言

maven不仅仅只是项目的依赖管理工具,其强大的核心来源自丰富的插件,可以说插件才是maven工具的灵魂。本篇文章将对如何自定义maven插件进行讲解,希望对大家有所帮助。

背景

讲如何开发maven插件之前,不妨先来聊一下什么是maven的插件。

我们知道,maven中主要有三大生命周期,clean,default和report,不同的生命周期中提供了一些快捷的操作命令给开发人员去进行项目的清理、编译、打包等操作。之所以我们可以通过类似于mvn clean compile等命令快速完成项目的清理和构建,实际上是因为maven在项目核心的生命周期节点上,已经设置好了默认的运行插件,我们执行命令的时候,实际上调用的就是绑定对应生命周期的插件。
maven插件本质上就是一个jar包,不同的插件里面有着不同功能的代码,当我们调用该插件的时候,其实就是通过执行jar包中的方法,去达到对应的goal,实现我们的目的。除了官网的maven插件之外,其实maven还允许我们根据实际的项目需要,自定义去开发maven插件,从而满足我们的项目构建需要。

demo演示

创建项目

  1. 打开 IntelliJ IDEA 工具,点击 “File”(文件)菜单,然后选择 “New”(新建),再选择 “Project”(项目)。
  2. 在弹出的对话框中,选择 “Maven” 选项,然后点击 “Next”(下一步)。
  3. 在 “New Project” 对话框中,输入项目的基本信息,如 “GroupId”、“ArtifactId”、“Version” 等。
  4. 在 “Project SDK” 下拉菜单中选择合适的 JDK 版本,然后点击 “Next”(下一步)。
  5. 在 “Project template” 对话框中,选择 “Maven Project”,并确保勾选 “Create from archetype”(从原型创建)。
  6. 在 “Choose archetype” 下拉菜单中,选择 “maven-archetype-mojo”。
  7. 点击 “Next”(下一步),然后输入项目的 “Name”(名称)和 “Location”(位置)。
  8. 点击 “Finish”(完成),IntelliJ IDEA 将会创建一个基本的 Maven 插件项目结构。
    在这里插入图片描述
    创建完成后项目结构如下:
    在这里插入图片描述
    这里的DescriptorGenerator是我重命名过的了,原本应该叫MyMojo

然后我们在pom文件中引入我们需要的依赖

<dependencies>
    <dependency>
      <groupId>org.apache.maven</groupId>
      <artifactId>maven-plugin-api</artifactId>
      <version>3.0</version>
    </dependency>
    <!--这个依赖引入了插件开发需要的相关注解-->
    <dependency>
      <groupId>org.apache.maven.plugin-tools</groupId>
      <artifactId>maven-plugin-annotations</artifactId>
      <version>3.4</version>
      <scope>provided</scope>
    </dependency>
     <!--将Maven文件解析成实体类的依赖-->
    <dependency>
      <groupId>org.apache.maven</groupId>
      <artifactId>maven-project</artifactId>
      <version>2.2.1</version>
    </dependency>
     <!--FreeMarker模板填充-->
    <dependency>
      <groupId>org.freemarker</groupId>
      <artifactId>freemarker</artifactId>
      <version>2.3.31</version>
    </dependency>
  </dependencies>

然后我们回到我们开发的主类DescriptorGenerator,类上加上@Mojo(name = “DescriptorPlugin”)注解,至此我们的项目骨架已经搭建完毕

业务介绍

我们的需求其实很简单,需要将项目根目录/descriptors下的两个文件填充pom文件中的version以及artifactId,并将生成的文件保存到target目录下,至此,代码就已经呼之欲出了:

/*
 * Copyright 2001-2005 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.project.MavenProject;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;

/**
 * Goal which touches a timestamp file.
 *
 * @goal touch
 * @phase process-sources
 */
@Mojo(name = "DescriptorPlugin")
public class DescriptorGenerator extends AbstractMojo {

    public void execute() throws MojoExecutionException {
        // 获取版本号及artifactId
        MavenProject project = (MavenProject) getPluginContext().get("project");
        Map<String, Object> dataModel = new HashMap<String, Object>();
        dataModel.put("version", project.getVersion());
        dataModel.put("artifactId",project.getArtifactId());
        System.out.println("Descriptor Generator Info: version : " + project.getVersion());
        System.out.println("Descriptor Generator Info: artifactId : " + project.getArtifactId());
        fillTemplate(dataModel,"DeploymentDescriptor.json");
        fillTemplate(dataModel,"ModuleDescriptor.json");
    }


    private void fillTemplate(Map<String, Object> dataModel,String fileName){
        String renderedContent = "";
        try {
            // 读取文件内容
            Configuration configuration = new Configuration(Configuration.VERSION_2_3_31);
            configuration.setDirectoryForTemplateLoading(new File("descriptors"));
            configuration.setDefaultEncoding("UTF-8");
            // 加载模板文件
            Template template = null;
            try {
                template = configuration.getTemplate(fileName);
            } catch (IOException e) {
                System.out.println("Descriptor Generator Error: File Not Found, File Path : " + "descriptors/" +fileName);
            }
            // 执行模板渲染
            StringWriter writer = new StringWriter();
            template.process(dataModel, writer);
            // 获取渲染后的内容
            renderedContent = writer.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 获取项目的 target 目录路径
        String targetDirectory = "target";
        // 创建 target 目录对象
        File targetDir = new File(targetDirectory);
        // 检查 target 目录是否存在,如果不存在则创建它
        if (!targetDir.exists()) {
            targetDir.mkdirs();
        }
        // 生成最终的文件路径
        String outputFile = targetDirectory + File.separator + fileName;
        System.out.println("Descriptor Generator Info: Output File : " + outputFile);
        FileWriter writer = null;
        try {
            writer = new FileWriter(outputFile);
            // 将处理后的文件内容写入生成的文件
            writer.write(renderedContent);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(writer != null){
                    writer.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}

Mojo已经给我们提供了一个AbstractMojo的抽象类,只需要继承于他,并且定义execute方法即可。

运行

接下去我们就将这个项目打包并且安装到本地仓库

mvn clean install

然后打开本地仓库,检查是否成功生成jar包
在这里插入图片描述

添加插件

我们打开我们的业务项目,在pom文件中,添加打包插件

<plugin>
    <artifactId>mod-shl-descriptor-generate</artifactId>
    <groupId>org.folio</groupId>
    <version>1.0.1</version>
    <executions>
        <execution>
            <id>test</id>
            <phase>compile</phase>
            <goals>
                <goal>DescriptorPlugin</goal>
            </goals>
        </execution>
    </executions>
</plugin>

其中DescriptorPlugin就是我们定义的@Mojo注解的值

运行

我们再业务项目中执行

mvn clean package

输出结果如下:
在这里插入图片描述
再看我们的target目录,那两个我们需要的文件也就出现在里面了

在这里插入图片描述

总结

至此,我们的maven插件就开发完毕了,可以看到整体开发难度并不是很高,但是可以实现的功能确十分强大。比如我们还可以通过定义注解的方式,打包阶段解析注解,生成我们想要的内容,或者提交到服务器完成类似于接口的注册等等功能。
学无止境,欢迎大家多多交流以及学习~

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

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

相关文章

STM32速成笔记—定时器

文章目录 一、什么是定时器二、定时器有什么用三、通用定时器详细介绍3.1 时钟来源3.2 预分频器&#xff0c;计数器&#xff0c;自动重装载寄存器3.2.1 预分频器3.2.2 计数器3.2.3 自动重装载寄存器 3.3 触发控制器 四、PWM4.1 什么是PWM4.2 什么是占空比4.3 STM32F1 PWM介绍4.…

【Python 随练】打印菱形图案

题目&#xff1a; 打印出如下图案&#xff08;菱形&#xff09; ********* ****************简介&#xff1a; 在本篇博客中&#xff0c;我们将使用Python代码打印一个菱形图案。我们将提供问题的解析&#xff0c;并给出一个完整的代码示例来生成这个菱形图案。 问题分析&am…

阿里云开源离线同步工具DataX3.0,用于数据仓库、数据集市、数据备份

DataX是阿里云开源的一款离线数据同步工具&#xff0c;支持多种数据源和目的地的数据同步&#xff0c;包括但不限于MySQL、Oracle、HDFS、Hive、ODPS等。它可以通过配置文件来定义数据源和目的地的连接信息、数据同步方式、数据过滤等&#xff0c;从而实现数据的高效、稳定、可…

C++初阶—完善适配器(反向迭代器)

目录 0. 前言 1、反向迭代器定义 2、反向迭代器需要实现的相关函数 3、反向迭代器分析 4、针对vector物理空间结构分析 5、针对list物理空间结构分析 6、反向迭代器适配器的实现及测试 0. 前言 本篇文章主要根据前面所实现的STL中支持迭代器的容器进行完善&#xff0c;使…

Mysql数据库日志和数据的备份恢复(去看一看海吧)

文章目录 一、数据库备份的重要性二、数据库备份的分类1.物理备份&#xff1a;对数据库操作系统的物理文件&#xff08;如数据文件、日志文件等)的备份。2.逻辑备份&#xff1a;对数据库逻辑组件&#xff08;如表等数据库对象&#xff09;的备份&#xff0c;导出sql文件。3.完全…

被卖到 2w 的 ChatGPT 提示词 Prompt 你确定不想要吗?

有朋友说&#xff0c;用 ChatGPT 生成的文案刻板化&#xff0c;格式化&#xff0c;而且往往也不是我想要的。‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍ 想要用好 ChatGPT 人工智能工具太难了&#xff0c;想一个好的提示词&#xff0c;也太不容易了&#xff0c;ChatGPT 就像一个宝藏…

3ds MAX绘制休闲椅

首先绘制一个长方形&#xff0c;并用上边两端点和底边中点绘制一个样条曲线 将上述曲线旋转复制&#xff0c;形成一个交叉的样条曲线&#xff0c;并移动两端点的位置&#xff0c;形成一上一下的结构 这就是休闲椅的大致形状 通过创建线将四个端点连接起来&#xff0c;形成空间…

UI组件——滑块简介

滑块控件是调整音量和亮度等设置的首选解决方案。它们立即生效&#xff0c;并允许用户通过移动手柄来微调值。滑块可以很好地达到目的&#xff0c;尤其是在精度不是很重要的情况下。 但是&#xff0c;这些控件可能会令人困惑&#xff0c;难以抓取并设置为精确值。另外&#xf…

人类智能的未来在于东西方智能的融合

有人认为&#xff1a;“只有时空的对齐&#xff0c;没有价值的对齐&#xff0c;智能或许就是智障”&#xff0c;即智能技术必须要与人类的价值观念和道德标准相一致&#xff0c;否则它所产生的结果可能会对人类社会造成负面影响。在现代社会中&#xff0c;智能技术已经越来越广…

【Elacticsearch】 分片副本机制,集群发现机制 ,负载机制,容错机制,扩容机制, 分片路由原理

集群发现机制 Elasticsearch采用了master-slave模式&#xff0c; ES会在集群中选取一个节点成为主节点&#xff0c;只有Master节点有资格维护全局的集群状态&#xff0c;在有节点加入或者退出集群的时候&#xff0c;它会重新分配分片&#xff0c;并将集群最新状态发送给集群中其…

Netty中的零拷贝机制

零拷贝机制(Zero-Copy)是在操作数据时不需要将数据从一块内存区域复制到另一块内存区域的技术,这样就避免了内存的拷贝,使得可以提高CPU的。零拷贝机制是一种操作数据的优化方案,通过避免数据在内存中拷贝达到的提高CPU性能的方案。 1.操作系统的零拷贝机制 操作系统的存储空间…

C++基础(5)——类和对象(3)

前言 本文主要介绍了C中类和对象的基本知识 4.3.1&#xff1a;成员变量和成员函数分开存储 只有非静态成员变量才属于类的对象上 C语言中结构体为空时使用sizeof&#xff08;&#xff09;打印的结果是0 C中类和结构体为空&#xff0c;用sizeof关键字可以算出是空类占1字节、…

OpenCV项目开发实战--图像识别和目标检测之(手写数字分类)

文末附基于Python和C++两种方式实现的测试代码下载链接 在本教程中,我们将使用 OpenCV 构建一个简单的手写数字分类器。一如既往,我们将分享用 C++ 和 Python 编写的代码。 最后两个帖子旨在提供了解基础知识所需的教育。这篇文章旨在提供成功实施图像分类器所需的培训。那么…

SpringBoot集成阿里云OSS实现图片存储服务

SpringBoot集成阿里云OSS实现图片存储服务 1、OSS概述2、账号申请2.1 购买服务2.2 创建Bucket 3、抽取模板工具OssProperties配置类OssTemplate模板对象AutoConfiguration配置类yml配置内容 4、测试 阿里云OSS&#xff08;Object Storage Service&#xff09;是一种强大的云存储…

ASO优化之关于应用商店的展示量

应用的展示数据代表应用在整个应用市场内的曝光次数&#xff0c;被展示的位置包括&#xff1a;首页精品推荐&#xff0c;搜索结果列表&#xff0c;应用详情页等。 应用的展示数据是衡量ASO搜索优化的关键指标。当关键词的覆盖数增加了&#xff0c;展示的次数没有增加&#xff…

【Nacos源码系列】服务注册的原理

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 文章目录 Nacos介绍服务注册客户端注册服务端 总结 Nacos介绍 Nacos是一个基于云原生的动态服务发现、配置管理和服务治理平台&#xff…

cppzmq编译和使用(ubuntu22.04)

libzmq libzmq&#xff0c;也称为 ZeroMQ&#xff0c;是一个高性能、异步消息传递库&#xff0c;用于构建分布式和并发系统。它提供了简单而强大的原语&#xff0c;使得开发者可以方便地在应用程序之间进行异步通信。 以下是对 libzmq 的详细介绍&#xff1a; 简介&#xff1…

VOC数据洞察在淘宝详情页的应用与实践

本专题共10篇内容&#xff0c;包含淘宝APP基础链路过去一年在用户体验数据科学领域&#xff08;包括商详、物流、性能、消息、客服、旅程等&#xff09;一些探索和实践经验&#xff0c;本文为该专题第二篇。 在商详页基于用户动线和VOC挖掘用户决策因子带来浏览体验提升&#x…

如何使用 PowerPoint 2021 制作演示文稿(PPT)?

软件安装&#xff1a;办公神器office2021安装教程&#xff0c;让你快速上手_正经人_____的博客-CSDN博客 引言 PowerPoint 是一款非常常用的演示文稿制作工具&#xff0c;它可以帮助您创建漂亮的幻灯片&#xff0c;展示您的想法和信息。如果您是 PowerPoint 的新手&#xff…

如何选择初始化向量【密码学】(5)

目录 一、分组算法如何计算 二、什么影响算法的安全性 三、密钥的使用次数限制 一、分组算法如何计算 分组算法包括3个部分&#xff1a;数据分组&#xff0c;分组运算和链接模式。 数据分组&#xff1a;将数据分割成加密函数能够处理的数据块&#xff0c;如果不能整分&#x…