在Linux下搭建自己的私有maven库并部署和发布自定义jar依赖和自定义maven插件(三)开发和发布自己开发的maven插件

news2024/11/18 11:35:44

系列文章目录

在Linux下搭建自己的私有maven库并部署和发布自定义jar依赖和自定义maven插件(二)发布自己开发的jar包


文章目录

  • 系列文章目录
    • 在Linux下搭建自己的私有maven库并部署和发布自定义jar依赖和自定义maven插件(二)发布自己开发的jar包
  • 前言
  • 一、插件需求
  • 二、maven自定义插件开发
    • 1、准备项目
    • 2、打包发布
  • 二、在项目中使用插件
  • 二、测试结果
  • 总结


前言

在上一节中我们分享了怎么开发和部署自己开发的jar包到maven私有库中,今天给大家介绍如何开发一个maven插件,我们在使用maven时,用的最多的就是maven的插件,而且这也是maven最核心的东西,maven的插件功能能帮助我们在构建、编译、发布项目的时候完成很多事情。有时我们在发布项目时可能会有一些我们定制化的处理,现有的插件都无法满足我们的需求,这时你可以自己开发一个插件来使用,下面我们用一个实际需求的案例来介绍如何开发自己的maven插件。


一、插件需求

记得曾经给一个客户开发了一套系统,采用Java+groovy的模式,大部分核心的逻辑在groovy中来实现,而且为了实现能差量更新,groovy部分将作为升级包,而且不进行编译,直接采用文件加载模式来执行,但是groovy又不能用原文的形式提供给客户,需要进行加密处理,因此为了项目打包方便,便开发了一个自己maven插件,在每次打包后对groovy部分的脚本内容进行加密处理后再统一制作成升级包。当然也可以手工来处理,但是利用maven插件会方便很多,下面给大家具体讲解每一个过程,相关的资源也已上传。

二、maven自定义插件开发

1、准备项目

开发maven插件其实和我们开发一个普通jar包过程是一样的,首先我们需要准备一个项目,
然后在pom.xml下添加如下两个依赖:

<dependency>
    <groupId>org.apache.maven</groupId>
    <artifactId>maven-plugin-api</artifactId>
    <version>3.5.0</version>
</dependency>
<dependency>
    <groupId>org.apache.maven.plugin-tools</groupId>
    <artifactId>maven-plugin-annotations</artifactId>
    <version>3.5</version>
    <scope>provided</scope>
</dependency>

其次我们在项目中添加一个类,需要继承org.apache.maven.plugin.AbstractMojo,代码如下:

@Mojo(name="encoder",defaultPhase= LifecyclePhase.GENERATE_SOURCES)
public class EncodeMojo extends AbstractMojo {
    @Parameter
    private String fromPath;
    @Parameter
    private String toPath;
    @Parameter
    private String secret;
    @Parameter
    private String iv;



    public EncodeMojo(String fromPath, String toPath,String secret, String iv) {
        this.fromPath = fromPath;
        this.toPath = toPath;
        this.secret = secret;
        this.iv = iv;
    }

    public EncodeMojo() {
    }

    @Override
    public void execute() throws MojoExecutionException, MojoFailureException {
    }
}

@Mojo注解

标识执行的动作,它对应的就是插件中的executions标签,我们可以定义多个Mojo,在使用时可以来执行不同的动作,比如上面我们定义的这个Mojo,在使用时的配置如下:

<executions>
	<execution>
		<phase>generate-resources</phase>
		<goals>
			<goal>encoder</goal>
		</goals>
	</execution>
</executions>

这里的phase和goal就对应上面的Mojo的定义

@Parameter注解

这里是插件的参数,这里需要注意的是,参数需要通过构造函数来初始化,它在实际的使用时对应的是configuration标签,比如上面的定义的配置如下:

<configuration>
	<fromPath>${project.basedir}/script</fromPath>
	<toPath>${project.basedir}/target/script</toPath>
	<secret>720cb14b3151490dad2afaf61d2919fb</secret>
	<iv>af3c77c3c6b747e6ad1006e47a1b8422</iv>
</configuration>

execute方法

插件要具体做的事情就在这个方法中来实现,上面我们的需求就是把fromPath里面的groovy脚本进行加密处理,然后再输出到toPath里面,secret和iv是加密的参数,具体的实现过程大家可以到顶部的资源处下载。

2、打包发布

参照上一节的jar包发布,其实过程都是一样的,如果不清楚可以点击:
在Linux下搭建自己的私有maven库并部署和发布自定义jar依赖和自定义maven插件(二)发布自己开发的jar包

查看,最重要的就是定义pom.xml里面的distributionManagement节点,和本地maven的settings.xml配置。具体不再详解,运行发布命令:

mvn clean -DskipTests deploy

执行完成后,我们登录Nexus后台,检查我们的插件是否发布成功。

在这里插入图片描述

已经发布成功了,下面我们在实际的项目中来使用。

二、在项目中使用插件

我们在准备一个项目来测试刚才我们的插件,根据需求,刚才我们的插件的作用是,把项目中的groovy脚本内容进行加密处理,然后制作成升级包。项目的结构如下:
在这里插入图片描述

现在我们在项目的pom.xml中加入下面的配置:
加入插件仓库源:

<pluginRepositories>
    <pluginRepository>
        <id>test-nexus</id>
        <name>test-nexus</name>
        <url>http://192.168.101.170:8081/repository/maven-public/</url>
        <releases>
            <enabled>true</enabled>
        </releases>
    </pluginRepository>
</pluginRepositories>

添加插件:

<plugin>
    <groupId>com.test</groupId>
    <artifactId>test-mvn-plugin</artifactId>
    <version>1.0</version>
    <configuration>
        <fromPath>${project.basedir}/groovy</fromPath>
        <toPath>${project.basedir}/target/script</toPath>
        <secret>720cb14b3151490dad2afaf61d2919fb</secret>
        <iv>af3c77c3c6b747e6ad1006e47a1b8422</iv>
    </configuration>
    <executions>
        <execution>
            <phase>generate-resources</phase>
            <goals>
                <goal>encoder</goal>
            </goals>
        </execution>
    </executions>
</plugin>

这里的作用就是把groovy目录下的文件,进行加密,然后输出到target/script目录,最后我们需要把script目录下的文件在打包成ZIP:

<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
    <id>package</id>
    <formats>
        <format>zip</format>
    </formats>
    <includeBaseDirectory>true</includeBaseDirectory>
    <fileSets>
        <fileSet>
            <directory>${project.build.directory}/script</directory>
            <outputDirectory>\script</outputDirectory>
        </fileSet>
    </fileSets>
</assembly>

在代码中我们这样使用:

package com.example.testmvnpkgexespringboot;

import com.example.testmvnpkgexespringboot.groovy.GroovyCompiler;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.File;
import java.io.IOException;

@SpringBootApplication
@RestController
public class TestMvnPkgExeSpringbootApplication {
    static File script_dir=new File("script");

    public static void main(String[] args) {
        SpringApplication.run(TestMvnPkgExeSpringbootApplication.class, args);
    }

    @Value("${script.secret}")
    private String secret;
    @Value("${script.iv}")
    private String iv;

    private GroovyCompiler groovyCompiler=new GroovyCompiler();

    @RequestMapping("/test/{script}")
    public Object test(@PathVariable String script){

        //读取script目录下的文件
        File file=new File(script_dir,script);
        if(!file.exists()){
            return  ResponseEntity
                    .notFound();
        }
        //解密groovy脚本
        String content= null;
        try {
            content = FileUtils.readFileToString(file);
        } catch (IOException e) {
            return  ResponseEntity
                    .badRequest().body("读取文件异常:"+e.getMessage())
                    ;
        }

        String de_content = AESCBCUtil.decryptAES_CBC(content,script,iv);
        if(StringUtils.isEmpty(de_content)){
            return  ResponseEntity
                    .badRequest().body("解密失败")
                    ;
        }
        //执行脚本

        return  groovyCompiler.compile(script,de_content).run();
    }

}

下面我们进行打包:

mvn clean -DskipTests package

二、测试结果

打包完成后,我们来看下结果:
在这里插入图片描述
我们发现脚本已经加密了,而且文件的后缀也改变了,这些就是在插件中完成的

最后我们来看下运行结果,groovy的原文如下:

def user=["id":1,"name":"csdn"]
return user;

我们来部署我们的项目,结构如下:
在这里插入图片描述
运行项目:

java -jar app.jar

然后访问:http://localhost:12345/test/get_user
在这里插入图片描述

结果和groovy中的代码一致,说明插件能正常使用


总结

1、利用maven的插件功能,不仅能帮助我们来构建项目使用,在有的客户需求其实也只需要开发一个maven插件就能满足,完全可以配合maven来完成一个业务需求。

2、上面项目中大家可以自行根据情况来调整相关的参数,我这里只是为了测试功能

3、maven开发的插件在gradle中也能完全使用

4、maven插件有完全的生命周期,大家可以参照官网的文档

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

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

相关文章

算法基础,一维,二维前缀和差分详解

目录 1.前缀和 1.一维前缀和 例题&#xff1a;【模板】前缀和 2.二维前缀和 例题&#xff1a;【模板】二维前缀和 2.差分 1.一维差分 1.性质&#xff1a;d[i]的前缀和等于a[i] 2.性质&#xff1a;后缀区间修改 例题&#xff1a;【模板】差分 2.二维差分 例题&#x…

(已解决)spingboot 后端发送QQ邮箱验证码

打开QQ邮箱pop3请求服务&#xff1a;&#xff08;按照QQ邮箱引导操作&#xff09; 导入依赖&#xff08;不是maven项目就自己添加jar包&#xff09;&#xff1a; <!-- 邮件发送--><dependency><groupId>org.springframework.boot</groupId><…

谷粒商城【成神路】-【4】——分类维护

目录 1.删除功能的实现 2.新增功能的实现 3.修改功能的实现 4.拖拽功能 1.删除功能的实现 1.1逻辑删除 逻辑删除&#xff1a;不删除数据库中真实的数据&#xff0c;用指定字段&#xff0c;显示的表示是否删除 1.在application.yml中加入配置 mybatis-plus:global-config:…

C语言:内存函数(memcpy memmove memset memcmp使用)

和黛玉学编程呀------------- 后续更新的节奏就快啦 memcpy使用和模拟实现 使用 void * memcpy ( void * destination, const void * source, size_t num ) 1.函数memcpy从source的位置开始向后复制num个字节的数据到destination指向的内存位置。 2.这个函数在遇到 \0 的时候…

关于node.js奇数版本不稳定 将11.x.x升级至16.x.x不成功的一系列问题(一)

据说vue2用16稳定一些 vue3用18好一点&#xff08;但之前我vue3用的16.18.1也可以&#xff09; 为维护之前的老项目 先搞定node版本切换 下载nvm node版本管理工具 https://github.com/coreybutler/nvm-windows/releases 用这个nvm-setup.zip安装包 安之前最好先将之前的nod…

Hadoop:HDFS学习巩固——基础习题及编程实战

一 HDFS 选择题 1.对HDFS通信协议的理解错误的是&#xff1f; A.客户端与数据节点的交互是通过RPC&#xff08;Remote Procedure Call&#xff09;来实现的 B.HDFS通信协议都是构建在IoT协议基础之上的 C.名称节点和数据节点之间则使用数据节点协议进行交互 D.客户端通过一…

搭建frp

1.frp 是什么&#xff1f; frp 是一款高性能的反向代理应用&#xff0c;专注于内网穿透。它支持多种协议&#xff0c;包括 TCP、UDP、HTTP、HTTPS 等&#xff0c;并且具备 P2P 通信功能。使用 frp&#xff0c;您可以安全、便捷地将内网服务暴露到公网&#xff0c;通过拥有公网…

【Mysql】事务的隔离级别与 MVCC

事务隔离级别 我们知道 MySQL 是一个 C/S 架构的服务&#xff0c;对于同一个服务器来说&#xff0c;可以有多个客户端与之连接&#xff0c;每个客户端与服务器连接上之后&#xff0c;就是一个会话&#xff08; Session &#xff09;。每个客户端都可以在自己的会话中向服务器发…

pytorch创建tensor

目录 1. 从numpy创建2. 从list创建3. 创建未初始化tensor4. 设置默认tensor创建类型5. rand/rand_like, randint6. randn生成正态分布随机数7. full8. arange/range9. linspace/logspace10. Ones/zeros/eye11. randperm 1. 从numpy创建 2. 从list创建 3. 创建未初始化tensor T…

LabVIEW核能设施监测

LabVIEW核能设施监测 在核能领域&#xff0c;确保设施运行的安全性和效率至关重要。LabVIEW通过与硬件的紧密集成&#xff0c;为高温气冷堆燃料装卸计数系统以及脉冲堆辐射剂量监测与数据管理系统提供了解决方案。这些系统不仅提高了监测和管理的精确度&#xff0c;也保证了核…

C++弹球游戏:Jump Ball Game

一、下载压缩包 请查看网站C弹球游戏&#xff1a;Jump Ball Game并且下载&#xff0c;可以看到如下界面&#xff1a; 二、匹配图标 把压缩包解压了&#xff1a; 右键点击Jump Ball Game.lnk&#xff0c;点击“属性”它将会是我们要运行的文件。 点击“更改图标”&#xff0c;选…

构建用于预警大型语言模型辅助生物威胁创建的系统

深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领域的领跑者。点击订阅&#xff0c;与未来同行&#xff01; 订阅&#xff1a;https://rengongzhineng.io/ 。 Op…

【Docker篇】Linux安装Docker、docker安装mysql、redis、rabbitmq

1.Linux安装docker 官方帮助文档&#xff1a;Install Docker Engine on CentOS | Docker Docs 1.1安装命令 # 1. 卸载之前的dockersudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate…

基于Python的招聘网站爬虫及可视化的设计与实现

摘要&#xff1a;现在&#xff0c;随着互联网网络的飞速发展&#xff0c;人们获取信息的最重要来源也由报纸、电视转变为了互联网。互联网的广泛应用使网络的数据量呈指数增长&#xff0c;让人们得到了更新、更完整的海量信息的同时&#xff0c;也使得人们在提取自己最想要的信…

Web3生态系统:构建去中心化的数字社会

随着科技的飞速发展&#xff0c;我们正处在迈向数字未来的道路上&#xff0c;而Web3生态系统则成为这一变革的中心。不仅仅是技术的演进&#xff0c;Web3代表着对传统互联网体系的颠覆&#xff0c;致力于构建一个去中心化的数字社会。本文将深入探讨Web3的核心特征、对金融、社…

澄清TypeScript中的 `satisfies` 操作符

TypeScript 的 satisfies 运算符已经推出一段时间了&#xff0c;但它似乎仍然是一个可以用来澄清的混乱来源。 可以把 satisfies 看作是将类型赋给值的另一种方式。 在我们深入研究之前&#xff0c;让我们回顾一下如何赋值类型。 首先&#xff0c;有一个不起眼的“冒号注解”…

用python实现pdf按页切割,以及将pdf转成图片

我们经常遇到需要切割pdf的时候&#xff0c;但是常规手段很难做到 我们可以利用python脚本来实现 需要安装几个库 tk PyPDF2 PyMuPDF pyinstaller 上图&#xff01; 查看结果 切割pdf转存成图像 那我们来详细说一下使用方法 1.输入PDF位置:这里没什么好说的&#xff0c…

基于SpringBoot开发的校刊投稿系统[附源码]

基于SpringBoot开发的校刊投稿系统[附源码] &#x1f345; 作者主页 央顺技术团队 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; &#x1f345; 查看下方微信号获取联系方式 承接各种定制系统 &#x1f…

【Springcloud篇】学习笔记十(十七章):Sentinel实现熔断与限流——Hystrix升级

第十七章_Sentinel实现熔断与限流 1.Sentinel介绍 1.1是什么 随着微服务的流行&#xff0c;服务和服务之间的稳定性变得越来越重要。 Sentinel 以流量为切入点&#xff0c;从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。 用来代替Hystrix Sentinel 具有…

[word] word大小写快捷键是什么? #知识分享#学习方法#笔记

word大小写快捷键是什么&#xff1f; word转换大小写的快捷方式是按“ShiftF3”。设置方法如下&#xff1a; 1、在电脑桌面找到需要转换大小写的文档&#xff0c;右键单击打开它。 2、打开文档之后&#xff0c;在文档里面选中需要转换的段落。 3、选中了之后在键盘里面找到“…