自定义Maven插件

时间:2021-08-15 17:17:31


最近又开始使用maven了,很长时间没有用它了,有一部分原因是对他没有完全掌握,今天我想把maven的使用彻底搞清楚,maven的工作模式是完全靠插件来完成的,所以

我决定自己写一个maven插件,这样 就能 对maven插件有更加的了解,因为自己在写一个简单的maven插件的时候,遇到了各种问题,现在做一下记录,也希望和我一样有需要的朋友可以参考一下。


在开始之前先把基础的知识再回顾一下,maven是定义了一系列的生命周期,如validate、compile、test、package等,关于生命周期更详细的介绍请参考 这里 .

生命周期是按顺序执行的,当执行后面的phase(状态)时,前面的也会执行,如执行 mvn validate 时,只会执行这一个phase,但是如果执行process-sources这个phase时,会依次执行 validate、generate-sources、 process-sources


关于pom的packaging策略,每个pom文件都有一个<packaging>元素,常见的内容有 jar、war等,那么这些代表什么呢,这个叫构建策略,通常这些策略有pom jar wai ejb等等,

我们通常在使用maven时,都是要指定goal 或者指定 phase的,如果直接调用一个goal就这样写 mvn dependency:copy-dependencies ,这样就执行了dependency插件的copy-dependencies这个goal, 也可以执行一个phase(我们通常是这样使用),如果说我们的pom文件没有构建策略的话(也就是没有packaging),那么如果我们执行 mvn install ,这样会有什么效果呢? 答案是什么效果也没有, 为什么呢?因为 maven会按顺序执行install前面的phase , validate 、compile、test等,还有install自己,但是因为前面说了maven是完全基于插件的,所有的功能都是由插件来完成的,如果没有packaging的话,结果就会是这样,(当然如果没有定义packaing元素的话,pom会默认为jar) , 那么我们再来说有了packaging会怎样,这里的packaing就 定义了一些插件和phase的对应关系, 也就是在某些phase上绑定了插件以及相应的goal,具体我们举个例子

如果packaging为jar ,以下就是绑定的插件,比如:在process-resources上就又maven-resources-plugin插件,compile时就有maven-compile-plugin插件

<phases>
<process-resources>
org.apache.maven.plugins:maven-resources-plugin:2.6:resources
</process-resources>
<compile>
org.apache.maven.plugins:maven-compiler-plugin:2.5.1:compile
</compile>
<process-test-resources>
org.apache.maven.plugins:maven-resources-plugin:2.6:testResources
</process-test-resources>
<test-compile>
org.apache.maven.plugins:maven-compiler-plugin:2.5.1:testCompile
</test-compile>
<test>
org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test
</test>
<package>
org.apache.maven.plugins:maven-jar-plugin:2.4:jar
</package>
<install>
org.apache.maven.plugins:maven-install-plugin:2.4:install
</install>
<deploy>
org.apache.maven.plugins:maven-deploy-plugin:2.7:deploy
</deploy>
</phases>
更多的packaing和插件的绑定情况请参考   这里


有了上面的知识介绍就可以开始插件开发了

1、生成插件项目,可以利用maven的archetype(原型)插件来生成相应的插件开发项目,这个插件也可以生成其他的项目,如web项目,java项目等等

mvn archetype:generate \
-DgroupId= net.csdn \
-DartifactId=hello-maven-plugin \
-DarchetypeGroupId=org.apache.maven.archetypes \
-DarchetypeArtifactId=maven-archetype-plugin
  说明:在maven中 -D是指定参数的方法 ,这里我们指定了 groupId为net.csdn,artifactId为hello-maven-plugin , 我们自定义的名称一般写为mypluginname-maven-plugin ,这样就生成了项目,如果为了在eclipse中开发方便,也可以将其转化为eclipse的项目,用eclipse插件 , 如 mvn eclipse:eclipse ,再导入到eclipse中。

2、请注意,项目生成好之后,还需要添加其他的依赖 ,不然无法正确的构建 插件(  官网的教程竟然也没写清楚 ,太让人伤脑经了 ), 

a、添加依赖

 <dependency>
            <groupId>org.apache.maven.plugin-tools</groupId>
            <artifactId>maven-plugin-annotations</artifactId>
            <version>3.2</version>
        </dependency>

b、在build元素中添加

</pre></p><p>这个插件是用来生成我们的插件的描述信息的,如果没有就不能构建插件</p><p><pre name="code" class="java">   <plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugin-plugin</artifactId>
<version>3.2</version>
<executions>
<execution>
<id>default-descriptor</id>
<goals>
<goal>descriptor</goal>
</goals>
<phase>process-classes</phase>
</execution>
<execution>
<id>help-descriptor</id>
<goals>
<goal>helpmojo</goal>
</goals>
<phase>process-classes</phase>
</execution>
</executions>
<configuration>
<skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
</configuration>
</plugin>
</plugins>



然后再来看java文件内容

@Mojo( name = "sayhi",defaultPhase=LifecyclePhase.COMPILE )
public class MyMojo
extends AbstractMojo
{
/**
* Location of the file.
* @parameter expression="${project.build.directory}"
* @required
*/
@Parameter(property="outputDirectory")
private File outputDirectory;

public void execute()
throws MojoExecutionException
{
this.getLog().info("ok le ....");
this.getLog().info("outputDirectory = "+ outputDirectory);

}

public File getOutputDirectory() {
return outputDirectory;
}

public void setOutputDirectory(File outputDirectory) {
this.outputDirectory = outputDirectory;
}
@Mojo就是一个goal,可以绑定到某个phase执行,@Parameter是从外面传进来的参数,关于其他类型参数的传递请参考 这里,上面的插件只是打印了一点内容,也 打印了传递的参数

3 、构建插件 , mvn install 

在命令行中可以看到已经将生成的插件安装到我们本地的repository中了,我们可以执行以下我们的插件,调用插件的goal的格式是这样的   groupId:artifactId:version:goal

所以我们这里是mvn  net.csdn:hello-maven-plugin:1.0:sayhi  -DoutputDirectory=e:\mm  ,这样就会调用这个插件了