Maven 插件
如果你的项目是基于maven构建,那么在项目的pom文件中,经常会看到这样的配置
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
在上面的代码中,我们使用了插件maven-compiler-plugin,这个插件的作用是将编写的java代码编译成指定的版本与编码的class文件。
Maven插件的组成
- goal
maven中的插件是有很多目标(goal)组成的,开发插件,实际上就是去编写插件中目标的具体代码。每个目标对应一个java类,这个类在maven中叫做MOJO,maven提供了一个Mojo的接口,我们开发插件也就是去实现这个接口
org.apache.maven.plugin.Mojo
通过goal我们可以定义插件在maven哪个生命周期中执行,比如上面的maven-compiler-plugin在compile阶段执行。
- configuration
插件执行阶段,我们可以通过配置定义各种参数,这样就能根据不同参数按需求执行插件,比如上面的maven-compiler-plugin中,在configuration 下的配置
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
maven-compiler-plugin的配置信息中,source和target属性指定了编译的java版本,encoding属性指定了编译结果的编码。
Maven插件的分类
Maven插件分为两种:
- 核心插件:Maven自带的插件,如maven-compiler-plugin,maven-surefire-plugin等。
- 非核心插件:第三方开发的插件,如sonar-maven-plugin,pmd-maven-plugin等。
插件的生命周期
Maven插件的生命周期分为三个阶段:
- 初始化阶段:在这个阶段,Maven会将插件的配置信息加载到一个org.apache.maven.plugin.Plugin对象中,这个对象中包含了插件的配置信息,如插件的id,version,dependencies等。
- 执行阶段:在这个阶段,Maven会调用插件的execute()方法,这个方法就是插件的核心,这个方法的执行是有顺序的,先执行initialize()方法,然后执行execute()方法
- 销毁阶段:在这个阶段,Maven会调用插件的cleanup()方法,这个方法的执行是无顺序的,先执行execute()方法,然后执行cleanup()方法。
Maven插件的执行
Maven插件的执行分为两种:
- 手动执行:在命令行中,使用mvn插件的id,如mvn compiler:compile,这个命令会先执行插件的初始化阶段,然后执行插件的执行阶段,最后执行插件的销毁阶段。
- 自动执行:在pom.xml文件中配置插件的执行,如maven-compiler-plugin,这个配置会先执行插件的初始化阶段,然后执行插件的执行阶段,最后执行插件的销销毁阶段。
比如基于idea时,我们可以在Maven工具栏,通过Lifecycle菜单中,选择相应的生命周期函数,然后点击Run按钮,即可执行插件。比如插件配置的在compile阶段执行,那么配置在compile对应的goal都会触发。
同样我们可以直接通过mvn命令调用插件,这样插件就不需要依赖于maven的生命周期函数取执行了。
// mvn groupId:artifactId:goal -Dprop=value
mvn com.sucls.blog:build-maven-plugin:printDate -Dname=XX
如何写一个Maven插件?
下面通过一个简单的示例来演示如何写一个Maven插件。
- 创建一个maven项目
- 添加相关依赖
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>${maven-plugin-api.version}</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>
<version>${maven-plugin-annotations.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
- 编写插件代码
@Mojo(name = "printDate")
public class PrintDatePlugin extends AbstractMojo {
@Parameter(property = "name",defaultValue = "printDate")
private String name;
@Parameter(property = "description",defaultValue = "打印日期插件")
private String description;
@Parameter(property = "format",defaultValue = "yyyy-MM-dd HH:mm:ss")
private String format;
@Override
public void execute() throws MojoExecutionException, MojoFailureException {
Date date = new Date();
Log log = getLog();
log.info(StringUtils.repeat("=",20));
log.info(String.format("开始执行插件:%s", name));
log.info(String.format("插件信息:%s", description));
log.info(String.format("执行插件:%s", DateFormatUtils.format(date,format)));
log.info(StringUtils.repeat("=",20));
}
}
- 打包插件
// 执行下面的命令 或者通过 idea中maven工具栏的package直接打包
mvn clean package
- 使用插件 创建一个新的项目,在pom.xml中添加插件的配置信息
<build>
<plugins>
<plugin>
<groupId>com.sucls.blog</groupId>
<artifactId>build-maven-plugin</artifactId>
<version>${project.version}</version>
<executions>
<execution>
<id>print-date</id>
<phase>compile</phase>
<goals>
<goal>printDate</goal>
</goals>
<configuration>
<name>PD</name>
<format>yyyy-MM-dd</format>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
- 执行插件
mvn clean complie
观察控制台可以看到这样的信息:
[INFO] --- build-maven-plugin:1.0-SNAPSHOT:printDate (print-date) @ build-maven-plugin ---
[INFO]
[INFO] ===============
[INFO] 开始执行插件:PD
[INFO] 插件信息:打印日期插件
[INFO] 执行插件:2023-12-05
[INFO] ===============
上面的示例中,主要做了下面的事情:
- 定义了一个打印日期的插件 也就是一个maven项目
- 为插件定义goal 一个goal也就是一个org.apache.maven.plugin.Mojo类,通过@Mojo注解,定义了插件的名称和goal,一个插件中可以包含多个goal,在配置时同样可以对应多个
- 为插件添加参数 在每一个Mojo中,通过@Parameter定义插件相关参数,这样在插件执行阶段即可通过参数完成对应逻辑
- 在其他项目中引入插件 在pom文件中,像其他插件一样通过groupId:artifactId:version引入自己定义的插件,配置maven的哪个生命周期阶段执行插件的goal,以及插件的参数。
- 使用插件 maven生命周期中,各个阶段都会找到所关联的插件并执行。
结束语
通过maven插件,可以根据我们的项目,定义一些重复,但耗时的编码工作,通过插件的形式,可以自动化完成这些工作,从而提高开发效率。