1.Maven
Maven 作為一個(gè)優(yōu)秀的項(xiàng)目管理工具蚪战,其插件機(jī)制為其功能擴(kuò)展提供了非常大的便捷性饭弓。雖然說大多數(shù)情況下废士,我們可能不太會(huì)自己去編寫 Maven 插件淋肾,但不排除在某些特殊的情況下硫麻,我們需要去完成一個(gè)自己的插件,來協(xié)助我們處理某些比較通用的事情樊卓。
2.Maven 插件的命名規(guī)范
一般來說庶香,我們會(huì)將自己的插件命名為<myplugin>-maven-plugin,而不推薦使用maven-<myplugin>-plugin简识,因?yàn)楹笳呤?Maven 團(tuán)隊(duì)維護(hù)官方插件的保留命名方式赶掖,使用這個(gè)命名方式會(huì)侵犯 Apache Maven 商標(biāo)感猛。
3.什么是 Mojo?
Mojo 就是Maven plain Old Java Object奢赂。每一個(gè) Mojo 就是 Maven 中的一個(gè)執(zhí)行目標(biāo)(executable goal)陪白,而插件則是對(duì)單個(gè)或多個(gè)相關(guān)的 Mojo 做統(tǒng)一分發(fā)。一個(gè) Mojo 包含一個(gè)簡(jiǎn)單的 Java 類膳灶。插件中多個(gè)類似 Mojo 的通用之處可以使用抽象父類來封裝咱士。
4.創(chuàng)建 Mojo 工程
這里,我們使用 idea 作為開發(fā)工具進(jìn)行講解轧钓,創(chuàng)建工程選擇 Maven序厉,然后在模板中找到 maven-archetype-plugin,點(diǎn)擊下一步毕箍,輸入對(duì)應(yīng)的參數(shù)弛房,如:io.fredia/test-maven-plugin/1.0-SNAPSHOT,最后點(diǎn)擊完成即可創(chuàng)建一個(gè)簡(jiǎn)單的 Mojo 工程而柑。
創(chuàng)建完成后文捶,工程內(nèi)會(huì)生成對(duì)應(yīng)的 pom.xml 文件。其內(nèi)容比較簡(jiǎn)單媒咳,與普通 Maven 工程的 pom.xml 基本一致粹排,只是自動(dòng)添加了對(duì) maven-plugin-api 的依賴,這個(gè)依賴?yán)锩鏁?huì)包含一些 Mojo 的接口與抽象類涩澡,在后續(xù)編寫具體的 Mojo 時(shí)再進(jìn)行詳細(xì)講解顽耳。
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>
<version>3.2</version>
</dependency>
注意打包方式:
<packaging>maven-plugin</packaging>
5.Mojo 的創(chuàng)建
工程創(chuàng)建完畢后,創(chuàng)建一個(gè)簡(jiǎn)單MoJo
package io.fredia.test;
/*
* Copyright 2001-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
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;
/**
* Goal which touches a timestamp file.
*
* @deprecated Don't use!
*/
@Mojo(name = "hello", defaultPhase = LifecyclePhase.PROCESS_SOURCES)
public class MyMojo extends AbstractMojo {
/**
* Location of the file.
*/
/*
* @Parameter(defaultValue = "${project.build.directory}", property =
* "outputDir", required = true) private File outputDirectory;
*/
public void execute() throws MojoExecutionException, MojoFailureException {
System.out.println("hello world");
}
}
解釋一下這個(gè)類妙同,我們發(fā)現(xiàn)它繼承了 AbstractMojo 這個(gè)抽象類射富,并實(shí)現(xiàn)了 execute() 方法,該方法就是用來定義這個(gè) Mojo 具體操作內(nèi)容渐溶,我們只需要根據(jù)自己的需要來編寫自己的實(shí)現(xiàn)即可辉浦。
Mojo 操作的實(shí)現(xiàn)我們了解了弄抬,那怎么讓 Maven 知道這是一個(gè) Mojo 而不是一個(gè)普通的 Java 類呢茎辐?這里,就需要說一下 Mojo 的查找機(jī)制了掂恕,在處理源碼的時(shí)候拖陆,plugin-tools 會(huì)把使用了 @Mojo 注解或 Javadoc 里包含 @goal 注釋的類來當(dāng)作一個(gè) Mojo 類。在上面的例子中懊亡,我們使用了 @MoJo 的方法來聲明一個(gè) Mojo依啰。同樣我們也可以使用 Javadoc 注解來進(jìn)行聲明:
/**
* @goal hello
*/
public class MyMojo extends AbstractMojo {
public void execute() throws MojoExecutionException, MojoFailureException {
System.out.println("hello fredia");
}
}
6.如何運(yùn)行自定義 Plugin
與使用其它插件類似,我們需要在 pom.xml 文件中引入插件:
<build>
<plugins>
<plugin>
<groupId>io.fredia</groupId>
<artifactId>test-maven-plugin</artifactId>
<version>1.0-SNAPSHOT</version>
</plugin>
</plugins>
</build>
mvn命令行執(zhí)行如下:
mvn io.fredia:test-maven-plugin:1.0-SNAPSHOT:hello
即可看到輸出:
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building test-maven-plugin Maven Mojo 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- test-maven-plugin:1.0-SNAPSHOT:hello (default-cli) @ test-maven-plugin ---
hello fredia
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.249 s
[INFO] Finished at: 2017-11-22T12:59:47+08:00
[INFO] Final Memory: 6M/123M
[INFO] ------------------------------------------------------------------------
7.縮短執(zhí)行命令
在剛才運(yùn)行插件的時(shí)候店枣,我們使用全量的插件指引速警,但這個(gè)實(shí)在是太長(zhǎng)太繁瑣了叹誉,那我們是否可以縮短我們的執(zhí)行命令呢?答案肯定是可以的闷旧,如果你想要執(zhí)行的是你本地庫中最新版本的插件长豁,那么你可以刪除掉版本號(hào);如果你的命名滿足前面提及的兩種命令方式忙灼,你可以直接使用插件名及 goal 名來運(yùn)行對(duì)應(yīng)的插件匠襟,如:
mvn test:hello
結(jié)果一樣
8.綁定 Maven 執(zhí)行周期
你還可以將插件配置為將特定目標(biāo),從而附加到構(gòu)建生命周期中的某個(gè)特定階段该园。如:
<build>
<plugins>
<plugin>
<groupId>io.fredia</groupId>
<artifactId>test-maven-plugin</artifactId>
<version>1.0-SNAPSHOT</version>
<executions>
<execution>
<goals>
<goal>hello</goal>
</goals>
<phase>package</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
最后附加一個(gè)自己基于maven-plugin開發(fā)的代碼生成器酸舍,實(shí)現(xiàn)高度的代碼復(fù)用和全自動(dòng)化