# 1. 背景
Maven 作为一个优秀的项目管理工具,其插件机制为其功能扩展提供了非常大的便捷性。虽然说大多数情况下,我们可能不太会自己去编写 Maven 插件,但不排除在某些特殊的情况下,我们需要去完成一个自己的插件,来协助我们处理某些比较通用的事情。
# 2. 使用方法
## 2.1 Maven 插件的命名规范
一般来说,我们会将自己的插件命名为**-maven-plugin**,而不推荐使用**maven--plugin**,因为后者是 Maven 团队维护官方插件的保留命名方式,使用这个命名方式会侵犯 Apache Maven 商标。
## 2.2 什么是 Mojo
Mojo 就是**Maven plain Old Java Object**。每一个 Mojo 就是 Maven 中的一个执行目标(***executable goal***),而插件则是对单个或多个相关的 Mojo 做统一分发。一个 Mojo 包含一个简单的 Java 类。插件中多个类似 Mojo 的通用之处可以使用抽象父类来封装。
## 2.3 创建 Mojo 工程
这里,我们使用 idea 作为开发工具进行讲解,创建工程选择 Maven,然后在模板中找到 maven-archetype-plugin,点击下一步,输入对应的参数,如:io.fredia/test-maven-plugin/1.0-SNAPSHOT,最后点击完成即可创建一个简单的 Mojo 工程。

创建完成后,工程内会生成对应的 pom.xml 文件。其内容比较简单,与普通 Maven 工程的 pom.xml 基本一致,只是自动添加了对 maven-plugin-api 的依赖,这个依赖里面会包含一些 Mojo 的接口与抽象类,在后续编写具体的 Mojo 时再进行详细讲解。
```
org.apache.maven
maven-plugin-api
2.0
org.apache.maven.plugin-tools
maven-plugin-annotations
3.2
```
**注意打包方式:**
```maven-plugin ```
## 2.4 Mojo 的创建
工程创建完毕后,创建一个简单MoJo
```
package io.fredia.test;
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;
@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");
}
}
```
解释一下这个类,我们发现它继承了 AbstractMojo 这个抽象类,并实现了 execute() 方法,该方法就是用来定义这个 Mojo 具体操作内容,我们只需要根据自己的需要来编写自己的实现即可。
Mojo 操作的实现我们了解了,那怎么让 Maven 知道这是一个 Mojo 而不是一个普通的 Java 类呢?这里,就需要说一下 Mojo 的查找机制了,在处理源码的时候,plugin-tools 会把使用了 @Mojo 注解或 Javadoc 里包含 @goal 注释的类来当作一个 Mojo 类。在上面的例子中,我们使用了 @MoJo 的方法来声明一个 Mojo。同样我们也可以使用 Javadoc 注解来进行声明:
```
public class MyMojo extends AbstractMojo {
public void execute() throws MojoExecutionException, MojoFailureException {
System.out.println("hello fredia");
}
}
```
## 2.5 运行自定义 Plugin
与使用其它插件类似,我们需要在 pom.xml 文件中引入插件:
```
io.fredia
test-maven-plugin
1.0-SNAPSHOT
```
mvn命令行执行如下:
```
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] ------------------------------------------------------------------------
```
## 2.6 缩短执行命令
在刚才运行插件的时候,我们使用全量的插件指引,但这个实在是太长太繁琐了,那我们是否可以缩短我们的执行命令呢?答案肯定是可以的,如果你想要执行的是你本地库中最新版本的插件,那么你可以删除掉版本号;如果你的命名满足前面提及的两种命令方式,你可以直接使用插件名及 goal 名来运行对应的插件,如:
```
mvn test:hello
```
结果一样
## 2.7 绑定 Maven 执行周期
你还可以将插件配置为将特定目标,从而附加到构建生命周期中的某个特定阶段。如:
```
io.fredia
test-maven-plugin
1.0-SNAPSHOT
hello
package
```
最后附加一个自己基于maven-plugin开发的代码生成器,实现高
度的代码复用和全自动化
# 3.总结
gitee地址:https://gitee.com/fredia/code-factory/
现在的项目都是模块化开发,所以这些边缘模块理应变得更加低耦合,每个模块做好自己的事情。

Maven-插件编写-之--Mojo