Maven : 自定义 Plugin 入门

1,578 阅读3分钟

首先分享之前的所有文章 , 欢迎点赞收藏转发三连下次一定 >>>> 😜😜😜
文章合集 : 🎁 juejin.cn/post/694164…
Github : 👉 github.com/black-ant
CASE 备份 : 👉 gitee.com/antblack/ca…

一 . 前言

自定义 Plugin 可以帮助我们提高开发效率 , 让一些非业务的功能性代码以插件的形式在多个项目中复用.

这一篇就来学习一下如何自定义 Plugin 插件以及写一个简单的插件.

二 . 知识点

Maven是Apache旗下的项目管理工具,它有Java语言开发,可以帮助我们更方便的管理和构建Java项目 . 而Maven 中自定义 Plugin 实际上和写一个项目没什么区别 , 只不过它的运行生命周期是在 Maven 构建的阶段进行.

Maven 插件的内部关系

2.1 Maven 依赖

既然Maven是基于 Java 的一种项目 , 那么他自然可以有 Maven 依赖 , 下面是最常见的几种 Maven 依赖 :

  • org.apache.maven # maven-plugin-api :
  • org.apache.maven.plugin-tools # maven-plugin-annotations :
  • org.apache.maven # maven-project :

2.2 Maven 中的 Mojo 对象

Maven 插件中最重要的概念就是 Mojo , 它用于标识一个 Mojo 对象 , 一个插件由任意数量的Mojo组成 . 通常一个Mojo 对象由2个部分组成 :

@Mojo( name = "sayhi")
public class GreetingMojo extends AbstractMojo{
    public void execute(){....}
}

// 对应的该类会抛出2个异常 : 
- org.apache.maven.plugin.MojoExecutionExceptio
- org.apache.maven.plugin.MojoFailureException


// Mojo 提供的 API : 
- setLog / getLog : 日志输出方法 , 允许Maven注入日志机制
- execute : Mojo 主要触发器 , 该触发器可以抛出 MojoExecutionException  以传递异常


// Mojo 注解解析 : 
- aggregator : 标记这个 Mojo 以多模块的方式运行 , 会把列为模块的项目集合在一起
- configurator : 把参数注入 Mojo 时要使用的配置器类型
- executionStrategy : 执行策略
- inheritByDefault : Mojo 是否是继承的
- instantiationStrategy : 实例化策略
- requiresProject : 将此 Mojo 标记为在项目内部运行
- requiresReports : 标记此 Mojo 以要求报告
- requiresOnline : 标记为需要在线模式才能运行

// 其他的可见 @ https://maven.apache.org/developers/mojo-api-specification.html

2.3 Maven 中的其他对象

Parameter 参数

Parameter 用于标注一个 Mojo 参数

// S1 : 注解标注参数
@Parameter( property = "sayhi.greeting", defaultValue = "Hello World!" )
@Parameter( property = "${project.version}", defaultValue = "Hello World!" )
private String greeting;

// S2 : 自定义参数的配置
<configuration>
  <greeting>Welcome</greeting>
</configuration>


// >> 另外可以使用简约模式
@Parameter
private boolean myBoolean;
<myBoolean>true</myBoolean>

private Date myDate;
<myDate>2005-10-06 2:22:55.1 PM</myDate>


// 使用数组 (使用List同理 ,list接收即可)
@Parameter
private String[] myArray;
<myArray>
  <param>value1</param>
  <param>value2</param>
</myArray>


// 使用 Map
<myMap>
  <key1>value1</key1>
  <key2>value2</key2>
</myMap>

// 使用对象
<myProperties>
  <property>
      <name>propertyName1</name>
      <value>propertyValue1</value>
  </property>
  <property>
      <name>propertyName2</name>
      <value>propertyValue2</value>
  </property>
</myProperties>

三 . 简单案例

3.1 编写插件

编写 Plugin 插件和编写 Jave 项目的流程是一样的 :

S1 : Maven Pom

  • packaging 为 maven-plugin
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.gang</groupId>
    <artifactId>ant-maven-plugin</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>maven-plugin</packaging>

    <properties>
        <maven.compiler.target>1.8</maven.compiler.target>
        <maven.compiler.source>1.8</maven.compiler.source>
    </properties>


    <dependencies>
        <dependency>
            <groupId>org.apache.maven</groupId>
            <artifactId>maven-plugin-api</artifactId>
            <version>3.6.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.maven.plugin-tools</groupId>
            <artifactId>maven-plugin-annotations</artifactId>
            <version>3.6.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.maven</groupId>
            <artifactId>maven-project</artifactId>
            <version>2.2.1</version>
        </dependency>
    </dependencies>


    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-plugin-plugin</artifactId>
                <version>3.6.4</version>
            </plugin>
        </plugins>
    </build>
</project>

S2 : 编写代码

  • 使用 @Mojo 注解
  • 继承 AbstractMojo 对象
@Mojo(name = "mojo-dependency-sample", defaultPhase = LifecyclePhase.COMPILE)
public class DependencyCounterMojo extends AbstractMojo {

    @Parameter(defaultValue = "${project}", required = true, readonly = true)
    MavenProject project;

    @Override
    public void execute() throws MojoExecutionException, MojoFailureException {
        List<Dependency> dependencies = project.getDependencies();
        long numDependencies = dependencies.stream().count();
        getLog().info("Number of dependencies: " + numDependencies);
    }
}

3.2 运行 Plugin 插件

// 标准运行公式
mvn groupId:artifactId:version:goal

// 常规运行方式
mvn com.gang:ant-maven-plugin:1.0-SNAPSHOT:mojo-dependency-sample

// 如果是最新版本 
mvn com.gang:ant-maven-plugin:mojo-dependency-sample

// 如果配置了前缀 , 即使用  ${prefix}-Maven-plugin 方式
mvn ant:mojo-dependency-sample

// 通过 Setting 配置 Plugun Group
> mvn ant:mojo-dependency-sample
<pluginGroups>
  <pluginGroup>sample.plugin</pluginGroup>
</pluginGroups>

3.3 Maven 插件 Debug

此处涉及到2个项目 : 
- Debug 项目 : 业务上使用插件的项目
- Plugin 项目 : Maven 插件源码项目


// S1 :  Debug 项目通过 mvndebug 运行 maven 命令
mvndebug com.gang:ant-maven-plugin:1.0-SNAPSHOT:mojo-dependency-sample
> Listening for transport dt_socket at address: 8000
> 

// S2 : Plugin 项目 Remote 远程调试触发 Debug 流程
> Plugin 项目启动后 , 实际项目就会自动运行


image.png

3.4 为MavenPlugin 配置 生命周期

配置后 ,该插件会在特定的生命周期中自动进行

<build>
    <plugins>
        <plugin>
            <groupId>com.gang</groupId>
            <artifactId>ant-maven-plugin</artifactId>
            <version>1.0-SNAPSHOT</version>
            <executions>
                <execution>
                    <phase>compile</phase>
                    <goals>
                        <goal>mojo-dependency-sample</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

四 . 补充信息

Maven Plugin 主要就是围绕 Project 进行扩展 , 这里扩展一下 MavenProject 的主要逻辑

// 获取 Properties 参数 , 并且设置参数
project.getProperties().put("dew.devops.skip", "true");

// 获取当前配置的plugin
List<org.apache.maven.model.Plugin> plugins = project.getBuildPlugins();
 
// 为model设置属性
project.getModel().addProperty("", "");

// 获取根路径
project.getBasedir()

// 获取包
project.getPackaging()

总结

Maven 插件的入门篇 , 下一篇会稍稍复杂的写一个 ReadMe 文档插件 , 用来输出指定格式的文档