系列文章目录

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



前言

在上一节中我们分享了怎么开发和部署自己开发的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 {
    }
}

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

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

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

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

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

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

2、打包发布

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

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

mvn clean -DskipTests deploy

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

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

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

二、在项目中使用插件

我们在准备一个项目来测试刚才我们的插件,根据需求,刚才我们的插件的作用是,把项目中的groovy脚本内容进行加密处理,然后制作成升级包。项目的结构如下:
在Linux下搭建自己的私有maven库并部署和发布自定义jar依赖和自定义maven插件(三)开发和发布自己开发的maven插件-LMLPHP

现在我们在项目的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

二、测试结果

打包完成后,我们来看下结果:
在Linux下搭建自己的私有maven库并部署和发布自定义jar依赖和自定义maven插件(三)开发和发布自己开发的maven插件-LMLPHP
我们发现脚本已经加密了,而且文件的后缀也改变了,这些就是在插件中完成的

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

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

我们来部署我们的项目,结构如下:
在Linux下搭建自己的私有maven库并部署和发布自定义jar依赖和自定义maven插件(三)开发和发布自己开发的maven插件-LMLPHP
运行项目:

java -jar app.jar

然后访问:http://localhost:12345/test/get_user
在Linux下搭建自己的私有maven库并部署和发布自定义jar依赖和自定义maven插件(三)开发和发布自己开发的maven插件-LMLPHP

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


总结

02-06 09:00