Maven 插件开发

官方文档: https://maven.apache.org/guides/plugin/guide-java-plugin-development.html 中译版:http://ifeve.com/maven-java-pluging/ Maven 只是一个框架,本身不执行什么功能,所有功能都是 Maven 插件完成的。比如编译命令是 `mvn compiler:compile` 就是使用 compiler 插件执行 compil 这个目标( goal`)。要想自己写一个 Maven 插件也是很简单的。

新建 Maven 工程

名字起为 {YourPluinName}-maven-plugin. 这样起名是 Maven 插件的规范,这样执行命令时可以使用简短命令(mvn YourPluginName:goal),否则需要输入 mvn groupId:artifacId:version:goal 全名。(version省略则使用最新版本)

引入依赖

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<dependency>
    <groupId>org.apache.maven</groupId>
    <artifactId>maven-plugin-api</artifactId>
    <version>3.0</version>
</dependency>

<!-- dependencies to annotations -->
<dependency>
    <groupId>org.apache.maven.plugin-tools</groupId>
    <artifactId>maven-plugin-annotations</artifactId>
    <version>3.4</version>
    <scope>provided</scope>
</dependency>
同时在 `build` 节点下加上
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<plugins>
  <!--https://www.oschina.net/question/565065_66878-->
  <!--需要这个插件才能编译-->
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-plugin-plugin</artifactId>
    <version>3.0</version>
    <configuration>
    <!-- Needed for Java 5 annotation based configuration, for some reason. -->
    <skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
  </configuration>
</plugin>

实现

然后添加一个类继承自 AbstractMojo 实现 execute() 方法即可。 为了能使这个方法能够执行,需要给添加的类冠上一个注解 @Mojo( name = "xxx" ) , 其中 xxx 就是这个插件的 goal, 一个插件可以有多个 Mojo, 就可以执行多个 goal. AbstractMojo 中有 getLog() 方法可以获取 Log, 我们的输出信息可以通过这个 Log 打印出来,而不要使用 sout. 如:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
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;
@Mojo(name = "hello")
public class HelloMojo extends AbstractMojo {
   public void execute() throws MojoExecutionException, MojoFailureException {
      getLog("Hello,World! My first Maven Plugin");
  }
}

使用

install 到本地仓库就可以在其他工程使用这个插件了。(有权限的话也可以 deploy 到远程仓库) 两种方法执行插件: 1. 对于随便一个 Maven 都可执行,直接在 pom.xml 同目录下执行:mvn gid:aid:goal 2. 修改 pom 文件:build > plugins 节点新增插件。
1
2
3
4
5
<plugin>
  <groupId>com.qunar.flight.international</groupId>
  <artifactId>hello-maven-plugin</artifactId>
  <version>1.0-SNAPSHOT</version>
 </plugin>
则可直接在 IDEA 右侧栏看到。也可以在本项目执行 mvn hello:hello, 其中第一个 hello 是 hello-maven-plugin 的前缀,第二个是 Mojo 注解的 goal. 若想每次编译都执行插件,而不用手动输入命令,则可以把插件绑定在 compile 生命周期。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<plugin>
  <groupId>com.qunar.flight.international</groupId>
  <artifactId>hello-maven-plugin</artifactId>
  <version>1.0-SNAPSHOT</version>
  <executions>
    <execution>
      <phase>compile</phase>
      <goals>
        <goal>hello</goal>
      </goals>
    </execution>
  </executions>
</plugin>
添加在 build 中插件节点信息里即可。

参数

不过,这个 Hello, World! 真是什么功能都没有啊…… 我要访问项目源码,统计每个文件行数行吗? 只需在 Mojo 类中增加一个注解即可:
1
2
3
4
5
@Parameter(
  property = "hello.sourcedir",
  defaultValue = "${project.build.sourceDirectory}",
  required = true, readonly = true)
private File sourcedir;
这样,Maven 会自动把值注入字段内,你就可以在 execute 方法中使用这个字段了。 类似的表达式还有 ${project.build.testSourceDirectory}, ${project.basedir} 等。还可以通过 -D 传参,如:@Parameter(property="hello.name") String name; 可以在运行时通过 mvn gid:aid:hello -Dhello.name=World 传入代码中。

Reader Echoes

3 comments

  • #1420刘明野
    从百度点进来的,支持一下,希望楼主多多更新哈 呲牙
  • #1419c
    日常沙发 坏笑
  • #1418c
    日常坐沙发 坏笑

表情

评论提交后需经审核才会显示。