第一、自定义Maven插件概述
Mojo:Maven plain Old Java Object。每一个 Mojo 就是 Maven 中的一个执行目标(executable goal),而插件则是对单个或多个相关的 Mojo 做统一分发。
一个 Mojo 包含一个简单的 Java 类。插件中多个类似 Mojo 的通用之处可以使用抽象父类来封装。Maven插件项目的打包方式packaging必须为maven-plugin
第二、自定义插件Maven插件的实现
1、创建一个maven项目mavenplugin
2、引入maven依赖
<!--打包方式-->
<packaging>maven-plugin</packaging>
<dependencies>
<!--使用doc的方式-->
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>3.5.2</version>
</dependency>
<dependency><!--使用注解的方式-->
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>
<version>3.5.2</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugin-plugin</artifactId>
<version>3.5.2</version>
<!-- 插件执行命令前缀 -->
<configuration>
<goalPrefix>mp</goalPrefix>
<skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
</configuration>
</plugin>
</plugins>
</build>
3、自定义maven插件文档方式实现
/** * 使用文档的方式 * @goal hellMojoDemo */
public class PrintMojoDemo01 extends AbstractMojo { /** * path of the classes folder. * @parameter expression="${classFolderPath}" */
private String classFolderPath; /** * @parameter expression = "${application}" */
private String application; @Override public void execute() throws MojoExecutionException, MojoFailureException { System.out.println(classFolderPath); System.out.println(application); System.out.println("自定义maven文档形式"); } } /** * Mojo标注: * /** * *@goal CustomMavenMojo:表示该插件的服务目标 * *@phase compile:表示该插件的生效周期阶段 * *@requiresProject true:表示是否依托于一个项目才能运行该插件 * *@parameter expression="${name}":表示插件参数,使用插件的时候会用得到
相关依赖:
<!--使用doc的方式-->
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>3.5.2</version>
</dependency>
* */
4、自定义maven插件注解方式实现
PrintMojo继承了 AbstractMojo 这个抽象类,并实现了 execute() 方法,该方法就是用来定义这个 Mojo 具体操作内容,我们只需要根据自己的需要来编写自己的实现即可。
那么Maven 如何知道这是一个 Mojo 而不是一个普通的 Java 类呢? Mojo 的查找机制:在处理源码的时候,plugin-tools 会把使用了 @Mojo 注解或 Javadoc 里包含 @goal 注释的类来当作一个 Mojo 类。在上面的例子中,我们使用了 Javadoc 的方法来声明一个 Mojo。同样我们也可以使用 @Mojo 注解来进行声明。
/** * * @author yehui * * 该类就是maven自定义插件类 * */
// mojo注解就是maven插件的注解,具体什么我忘记了。name就是后面使用该插件的时候excuation里面的, // 后面配置的是生命周期,我这里配置了install,即默认是安装时候执行本插件(这个可以在pom文件指定)
@Mojo(name = "helpmojo",defaultPhase = LifecyclePhase.INSTALL) public class PrintMojo extends AbstractMojo { // // 配置的是本maven插件的配置,在pom使用configration标签进行配置 property就是名字, // 在配置里面的标签名字。在调用该插件的时候会看到
@Parameter(property = "application") private String application; @Parameter(property = "sourceFolderPath") private String sourceFolderPath; @Parameter(property = "driverName") private String driverName; @Parameter(property = "dbUrl") private String dbUrl; @Parameter(property = "dbName") private String dbName; @Override public void execute() throws MojoExecutionException, MojoFailureException { System.out.print("Hello World"); System.out.println(application); System.out.println(sourceFolderPath); System.out.println(driverName); System.out.println(dbUrl); System.out.println(dbName); } }
5、打包、安装到本地仓库
打包:mvn clean package
安装到本地仓库:mvn clean install
6、创建一个测试项目(maventest)
引入刚刚自定义的插件
<build>
<plugins>
<plugin>
<!--引入刚刚的插件依赖-->
<groupId>com.yehui</groupId>
<artifactId>mavenplugin</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 这里加入的是相关参数,这些参数必须跟插件实现里面的属性保持一致 -->
<configuration>
<application>api</application><!-- 当前应用名称 -->
<sourceFolderPath>${basedir}</sourceFolderPath><!-- 当前应用根目录 -->
<driverName>com.mysql.jdbc.Driver</driverName><!-- 数据库驱动 -->
<dbUrl>jdbc:mysql://10.16.88.189:3306</dbUrl><!-- 数据库连接URL -->
<dbName>iapps</dbName><!-- 数据库名 -->
<name>yehui</name>
</configuration>
</plugin>
</plugins>
</build>
效果:
双击运行:
源码地址:
https://github.com/yhcxy/sourceCode/tree/master/mavenplugin
第三、mojo参数详解
每个mojo都必须使用@Goal标注来表明其目标名称,否则maven将无法识别该目标。还有其他很多标注,列举如下:
@goal <name>:唯一必须声明的标注,当用户命令行调用或在pom中配置插件是,需使用该目标名称,如果你在运行compiler:compile目标,compiler就是插件的goalPrefix,compile就是目标的名称
@phase <phase>:默认将该目标绑定至default声明周期的某个阶段,这样在配置使用插件目标时,就无需声明phase,如maven-surefire-plugin的test目标带有@phase tes标注
@requiresDependencyResolution <scope>:在运行mojo之前必须解析所有指定范围的依赖,如maven-surefire-plugin的test目标带有requiresDependencyResolution test标注,表示执行测试前,所有测试范围的依赖必须得到解析
@requiresProject <true/false>:该目标是否必须在一个maven项目中运行(如测试插件用于测试其他项目),默认为true。大部分插件目标需依赖一个项目才能运行,但是,maven-help-plugin的system目标例外,它用来显示系统属性和环境变量信息,无需实际项目。
@requiresOnline <true/false>:是否要求maven必须是在线状态,默认值为false
@requiresReport <true/false>:是否要求项目报告已经生成,默认为false
@aggregator:当mojo在多模块项目上运行时,该标注表示目标只会在顶层模块运行。
@requiresDirectInvocation <true/false>:为true时,该目标就只能通过命令行直接调用。默认为false
@execute goal="<goal>":在运行该目标之前,让maven运行另外一个目标。如果是本插件目标,则直接调用目标名称,否则,使用“prefix:goal”
@execute phase="<phase>":在运行该目标前,让maven先运行一个并行的生命周期,到指定的阶段为止。到phase执行完,才执行插件目标
@execute lifecycle="<lifecycle>" phase = "<phase>":在运行该目标前,让maven先运行一个自定义的生命周期,到指定的阶段为止。
parameters:该元素描述Mojo的所有参数。name,type,required,editable(是否允许在pom.xml中设置),description,如可使用@parameter将mojo的某个字段标注为可配置参数,即mojo参数。支持boolean,int,float,String,Date,File,Url,数组,Collection,map,Propertes
configuration:为所有Mojo参数提供默认值)
第四、maven内置属性
1、maven属性
内置属性(maven预定义,用户可以直接使用的)
主要有两个常用内置属性——
${basedir}表示项目根目录,即包含pom.xml文件的目录;
${version}表示项目版本。
${project.basedir}同${basedir};
2、POM属性(使用pom属性可以引用到pom.xml文件对应的元素的值)
${project.build.sourceDirectory}:项目的主源码目录,默认为src/main/java/.
${project.build.testSourceDirectory}:项目的测试源码目录,默认为/src/test/java/.
${project.build.directory}:项目构建输出目录,默认为target/.
${project.outputDirectory}:项目主代码编译输出目录,默认为target/classes/.
${project.testOutputDirectory}:项目测试代码编译输出目录,默认为target/testclasses/.
${project.groupId}:项目的groupId.
${project.artifactId}:项目的artifactId.
${project.version}:项目的version,于${version}等价
${project.build.finalName}:项目打包输出文件的名称,默认 为${project.artifactId}${project.version}
自定义属性(在pom.xml文件的<properties>标签下定义的maven属性)
<project>
<properties>
<my.pro>proname</my.pro>
</properties>
</project>
在其他地方就可以使用该自定义的属性了:
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${my.pro}</version>
</dependency>
setting.xml文件属性(与pom属性同理,用户可以用以settings.开头的属性引用setting.xml文件的XML元素值)
${settings.localRepository}表示本地仓库的地址
java系统属性(所有的java系统属性都可以用env,开头的maven属性引用)
使用mvn help:system命令可查看所有环境变量;
${env.JAVA_HOME}表示JAVA_HOME环境变量的值;