maven插件开发
Maven 作为一个优秀的项目管理工具,其插件机制为其功能扩展提供了非常大的便捷性,本身它所有的功能都是插件完成的,maven自身只是一个框架。虽然说大多数情况下,我们可能不太会自己去编写 Maven 插件,但不排除在某些特殊的情况下,我们需要去完成一个自己的插件,来协助我们处理某些比较通用的事情,比如检查代码规范。插件和AOP掌握的好,开发效率绝对以一敌十。
Maven 插件的命名规范
一般来说,我们会将自己的插件命名为 <myplugin>-maven-plugin,而不推荐使用 maven-<myplugin>-plugin,因为后者是 Maven 团队维护官方插件的保留命名方式,使用这个命名方式会侵犯 Apache Maven 商标。可以说跟spring boot starter是一个路子。
什么是 Mojo?
Mojo 就是 Maven plain Old Java Object。每一个 Mojo 就是 Maven 中的一个执行目标(executable goal),而插件则是对单个或多个相关的 Mojo 做统一分发。一个 Mojo 包含一个简单的 Java 类,其中可以了目标名、执行阶段及相应的入参。插件中多个类似 Mojo 的通用之处可以使用抽象父类来封装。
第一个maven插件工程
maven插件工程本身是也是一个maven工程,唯一的区别是它的打包方式为maven-plugin,如下:
<packaging>maven-plugin</packaging>
其次,要依赖maven-plugin-api包开发,其中定义了maven插件开发必须的一些接口。如下:
<artifactId>csc-maven-plugin</artifactId> <name>csc-maven-plugin</name> <packaging>maven-plugin</packaging> <dependencies> <dependency> <groupId>org.apache.maven</groupId> <artifactId>maven-plugin-api</artifactId> <version>3.6.3</version> <scope>system</scope> <systemPath>D:/no-maven-jar/maven-plugin-api-3.6.3.jar</systemPath> </dependency> <dependency> <groupId>org.apache.maven.plugin-tools</groupId> <artifactId>maven-plugin-annotations</artifactId> <version>3.5</version> <scope>provided</scope> </dependency> </dependencies>
package com.xxx.fff.maven.plugin.csc; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; /** * @author zjhua * @description 检查工具,在package阶段执行 */ @Mojo(name="check") public class CodingStyleCheckMojo extends AbstractMojo { @Parameter(property = "prop1") private String prop; @Override public void execute() throws MojoExecutionException, MojoFailureException { System.out.println("执行规范检查" + prop); } }
execute可以抛出两个异常:
- org.apache.maven.plugin.MojoExecutionException:该异常标识发生非预期的错误,最后maven会展示"BUILD ERROR"。
- org.apache.maven.plugin.MojoFailureException:该异常标识发生可预期的错误,最后maven会展示BUILD FAILURE,一般来说应使用后者。
带参数的Mojo
实际中,不带参数的Mojo是很少的,而且作用也不是很大。只要在Mojo的属性上加上@Parameter注解,定义property属性即可。IDE可以自动识别插件的属性,如下:
@Parameter( property = "prop1", defaultValue = "你好!" ) private String prop;
参数可以支持各种类型,包括map、list、数组等,可参见:http://maven.apache.org/guides/plugin/guide-java-plugin-development.html。
maven插件的核心概念
maven的核心概念主要包括4个:lifecycle->phase->goal、mojo。
- lifecycle:生命周期,这是maven最高级别的的控制单元,它是一系列的phase组成,也就是说,一个生命周期,就是一个大任务的总称,不管它里面分成多少个子任务,反正就是运行一个lifecycle,就是交待了一个任务,运行完后,就得到了一个结果,中间的过程,是phase完成的,自己可以定义自己的lifecycle,包含自己想要的phase。常见的lifecycle有 | clean | package ear | pageage jar | package war | site等等。
- phase:可以理解为任务单元,lifecycle是总任务,phase就是总任务分出来的一个个子任务,但是这些子任务是被规格化的,它可以同时被多个lifecycle所包含,一个lifecycle可以包含任意个phase,phase的执行是按顺序的,一个phase可以绑定很多个goal,至少为一个,没有goal的phase是没有意义的。下面就是一些default lifecycle的phase:
validate
initialize
generate-sources
process-sources
generate-resources
process-resources
compile compile
process-classes
generate-test-sources
process-test-sources
generate-test-resources
process-test-resources
test-compile
process-test-classes
test
prepare-package
package
pre-integration-test
integration-test
post-integration-test
verify
install
deploy
- goal: 这是执行任务的最小单元,它可以绑定到任意个phase中,一个phase有一个或多个goal,goal也是按顺序执行的,一个phase被执行时,绑定到phase里的goal会按绑定的时间被顺序执行,不管phase己经绑定了多少个goal,你自己定义的goal都可以继续绑到phase中。
- mojo: lifecycle与phase与goal都是概念上的东西,mojo才是做具体事情的,可以简单理解mojo为goal的实现类,它继承于AbstractMojo,有一个execute方法,goal等的定义都是通过在mojo里定义一些注释的anotation来实现的,maven会在打包时,自动根据这些anotation生成一些xml文件,放在plugin的jar包里。
抛开mojo不讲,lifecycle与phase与goal就是级别的大小问题,引用必须是从高级引用下级(goal绑定到phase,也可理间为phase引用goal,只是在具体绑定时,不会phase定义引用哪些goal,但是执行是,却是phase调用绑定到它那的goal),也不能跨级引用,如lifecycle可以引用任意的phase,不同lifecycle可以同时引用相同的phase,lifecycle不能跨级引用goal。goal会绑定到任意的phase中,也就是说不同的phase可以同时引用相同的goal,所以goal可以在一个lifecycle里被重复执行哦,goal自然也不能说绑定到lifecycle中,它们三者的关系可以用公司里的 总领导,组领导,与职员的关系来解释。
入门开发:https://blog.csdn.net/chinrui/article/details/66472815
Maven官方插件开发文档:http://maven.apache.org/plugin-developers/index.html、http://maven.apache.org/plugin-developers/cookbook/index.html、http://maven.apache.org/guides/plugin/guide-java-plugin-development.html