maven自定义插件
Maven 自定义插件开发全指南:从实现到应用
Maven 插件是扩展 Maven 功能的核心方式,通过自定义插件,你可以将团队特有的构建逻辑、检查规则或部署流程集成到 Maven 生命周期中。本文将详细介绍如何开发、打包和使用自定义 Maven 插件。
自定义插件的核心概念
- Mojo:Maven 插件的最小执行单元(类似 “目标”),每个插件包含一个或多个 Mojo,每个 Mojo 对应一个具体功能(如代码检查、自定义打包)。
- 插件打包类型:自定义插件必须使用
<packaging>maven-plugin</packaging>声明。 - 注解驱动:通过
@Mojo注解定义 Mojo 元信息,@Parameter注解声明可配置参数。
开发自定义插件的步骤
1. 创建插件项目
新建一个 Maven 项目,修改 pom.xml 如下:
<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.zhanghe.study</groupId>
<artifactId>test-maven-plugin</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>maven-plugin</packaging> <!-- 插件必须使用此打包类型 -->
<name>Test Maven Plugin</name>
<description>A custom Maven plugin example</description>
<dependencies>
<!-- 插件核心依赖 -->
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>3.8.6</version> <!-- 推荐使用较新版本 -->
</dependency>
<!-- 注解处理器(简化 Mojo 配置) -->
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>
<version>3.6.4</version>
<scope>provided</scope> <!-- 编译时依赖 -->
</dependency>
</dependencies>
</project>
2. 实现 Mojo 类
每个 Mojo 类需继承 AbstractMojo 并实现 execute() 方法,通过注解定义元信息和参数。
示例:创建一个打印版本信息的 Mojo:
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
// 定义 Mojo 名称和默认绑定的生命周期阶段
public class VersionPrinterMojo extends AbstractMojo {
// 注入当前 Maven 项目信息(内置参数)
private MavenProject project;
// 自定义参数(可在 pom.xml 中配置)
private String prefix;
public void execute() throws MojoExecutionException, MojoFailureException {
// 获取项目版本(来自 pom.xml 的 version 字段)
String version = project.getVersion();
// 打印信息(使用 Maven 的日志接口,而非 System.out)
getLog().info(prefix + version);
}
}
关键注解说明:
@Mojo:定义 Mojo 核心属性:name:目标名称(如printVersion),调用时使用插件前缀:name。defaultPhase:默认绑定的生命周期阶段(如COMPILE),可省略(需手动绑定)。requiresProject:是否必须在 Maven 项目中运行(默认true)。
@Parameter:定义可配置参数:defaultValue:默认值,支持 Maven 表达式(如${project.version})。property:可通过命令行-Dproperty=value覆盖参数(如property = "version.prefix"则可通过-Dversion.prefix=XXX配置)。required:是否必须配置(未配置则报错)。readonly:是否只读(用户无法在 pom 中配置,通常用于注入内置对象如project)。
3. 打包插件到仓库
执行以下命令将插件安装到本地仓库(供本地项目使用):
mvn clean install
若需团队共享,可部署到私服(如 Nexus):
mvn clean deploy # 需在 pom.xml 中配置 distributionManagement
在项目中使用自定义插件
在目标项目的 pom.xml 中引入自定义插件,并配置参数:
<build>
<plugins>
<plugin>
<!-- 插件坐标(与自定义插件的 groupId、artifactId、version 一致) -->
<groupId>com.zhanghe.study</groupId>
<artifactId>test-maven-plugin</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 配置插件参数 -->
<configuration>
<prefix>当前项目版本:</prefix> <!-- 覆盖默认前缀 -->
</configuration>
<!-- 绑定到生命周期阶段(若 Mojo 未指定 defaultPhase) -->
<executions>
<execution>
<phase>compile</phase> <!-- 在 compile 阶段执行 -->
<goals>
<goal>printVersion</goal> <!-- 执行自定义 Mojo -->
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
执行插件目标
方式 1:通过生命周期阶段(推荐)
由于插件已绑定到 compile 阶段,执行以下命令会自动触发:
mvn compile
方式 2:直接调用目标
无需绑定生命周期,直接通过命令行调用:
mvn com.zhanghe.study:test-maven-plugin:1.0-SNAPSHOT:printVersion
方式 3:配置插件前缀(简化调用)
在插件项目的 pom.xml 中配置插件前缀(需部署到仓库):
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugin-plugin</artifactId>
<version>3.6.4</version>
<configuration>
<goalPrefix>custom</goalPrefix> <!-- 自定义前缀 -->
</configuration>
</plugin>
</plugins>
</build>
重新安装插件后,可通过前缀简化调用:
mvn custom:printVersion # 等价于完整坐标调用
高级特性
1. 处理异常
Mojo 执行时可抛出两种异常:
MojoFailureException:预期错误(如参数无效),Maven 会显示BUILD FAILURE。MojoExecutionException:非预期错误(如 IO 异常),Maven 会显示BUILD ERROR。
public void execute() throws MojoExecutionException, MojoFailureException {
if (prefix == null || prefix.isEmpty()) {
throw new MojoFailureException("参数 'prefix' 不能为空!");
}
// ...
}
2. 注入内置对象
Maven 提供了多种可直接注入的内置对象(通过 @Parameter):
${project}:当前项目信息(MavenProject类型)。${session}:Maven 会话(MavenSession类型)。${settings}:Maven 配置(Settings类型)。
private Settings settings;
public void execute() {
String localRepo = settings.getLocalRepository(); // 获取本地仓库路径
getLog().info("本地仓库位置:" + localRepo);
}
3. 多 Mojo 插件
一个插件可包含多个 Mojo 类,只需为每个类添加 @Mojo 注解并指定不同 name:
public class NamePrinterMojo extends AbstractMojo {
// ... 实现打印项目名称的逻辑
}
调用时指定不同目标:
mvn custom:printVersion # 调用第一个 Mojo
mvn custom:printName # 调用第二个 Mojo
调试自定义插件
在插件项目中添加调试配置(以 IDEA 为例):
- 新建 “Maven 运行 / 调试配置”。
- 命令行输入:
clean install -Dmaven.plugin.validation=VERBOSE。 - 勾选 “调试” 选项,启动调试。
在目标项目中通过远程调试:
mvn compile -Dmaven.surefire.debug # 触发调试模式