第一、自定義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環境變量的值;