• Maven提高篇系列之(六)——编写自己的Plugin(本系列完)


    这是一个Maven提高篇的系列,包含有以下文章:

    1. Maven提高篇系列之(一)——多模块 vs 继承
    2. Maven提高篇系列之(二)——配置Plugin到某个Phase(以Selenium集成测试为例)
    3. Maven提高篇系列之(三)——使用自己的Repository(Nexus)
    4. Maven提高篇系列之(四)——使用Profile
    5. Maven提高篇系列之(五)——处理依赖冲突
    6. Maven提高篇系列之(六)——编写自己的Plugin(本系列完)

      

    在本系列的上一篇文章中,我们讲到了如何处理依赖冲突,在本文中,我们将讲到如何编写自己的Plugin。

     

    Maven就其本身来说只是提供一个执行环境,它并不知道需要在项目上完成什么操作,真正操作项目的是插件(plugin),比如编译Java有Compiler插件,打包有Jar插件等。所以要让Maven完成各种各样的任务,我们需要配置不同的插件,甚至自己编写插件。

     

    你可能要问了:“我并没有配置什么插件啊,照样能编译打包。”这是因为Maven在默认情况下已经给我们配置了一些常用的插件,上面的Compiler和Jar便在这些插件之列。要查看Maven的默认插件,我们需要找到Super Pom,在笔者的电脑上,Super Pom位于M2_HOME/lib/maven-2.2.1-uber.jar文件中,文件名为pom-4.0.0.xml,里面包含了Maven所有的默认插件:

     

    <pluginManagement>       
           <plugins>       
             <plugin>       
               <artifactId>maven-antrun-plugin</artifactId>       
               <version>1.3</version>       
             </plugin>              
             <plugin>       
               <artifactId>maven-assembly-plugin</artifactId>       
               <version>2.2-beta-2</version>       
             </plugin>                
             <plugin>       
               <artifactId>maven-clean-plugin</artifactId>       
               <version>2.2</version>       
             </plugin>       
             <plugin>       
               <artifactId>maven-compiler-plugin</artifactId>       
               <version>2.0.2</version>       
             </plugin>  
              ......  
           </plugins>  
    </pluginManagement>  

    任何Maven工程默认都继承自这个Super Pom,你也可以在自己的项目中执行:        

     

    mvn help:effective-pom

     

    来查看包括继承内容的整个pom文件,其中便包含了从Super Pom继承下来的内容。

     

    和其他Maven项目一样,Maven的插件也是一种packaging类型(类型为maven-plugin),也拥有groupId,artifactId和version。简单地讲,一个Maven插件包含了一些列的goal,每一个goal对应于一个Mojo类(Maven Old Java Object,命名来自于Pojo),每个Mojo都需要实现org.apache.maven.plugin.Mojo接口,该接口定义了一个execute方法,在开发插件时,你的任务就是实现这个execute方法。

     

    (一)创建自己的插件

    接下来,我们来实现一个Maven插件,该插件输出项目的build目录信息。请下载本文的github源代码:https://github.com/davenkin/demo-maven-plugin

     

    先通过archetype创建一个Maven插件工程:

     

     mvn archetype:generate 
          -DgroupId=me.davenkin 
          -DartifactId=demo-maven-plugin 
          -DarchetypeGroupId=org.apache.maven.archetypes 
          -DarchetypeArtifactId=maven-archetype-mojo

    此时打开工程中的pom.xml文件,你可以看到该工程的packaging类型:

     

    <packaging>maven-plugin</packaging>

    向工程中添加一个Mojo类:

     

    /** 
    * @goal buildinfo 
    * @phase  pre-integration-test 
    */  
    public class BuildInfoMojo extends AbstractMojo {  
       
       /** 
        * @parameter expression="${project}" 
        * @readonly 
        */  
       private MavenProject project;  
       
       /** 
        * @parameter expression="${buildinfo.prefix}" 
        * default-value="+++" 
        */  
       private String prefix;  
       
       public void execute() throws MojoExecutionException {  
           Build build = project.getBuild();  
           String outputDirectory = build.getOutputDirectory();  
           String sourceDirectory = build.getSourceDirectory();  
           String testOutputDirectory = build.getTestOutputDirectory();  
           String testSourceDirectory = build.getTestSourceDirectory();  
           getLog().info("
    ==========================
    Project build info:");  
           String[] info = {outputDirectory, sourceDirectory, testOutputDirectory, testSourceDirectory};  
           for (String item : info) {  
               getLog().info("	" + prefix + "   " + item);  
           }  
           getLog().info("=======================");  
       }  
    }  

    在上面的代码中,“@goal buildinfo”表示该Mojo对应的goal的名字为buildinfo(在调用该goal时需要给出它的名字),“@phase   pre-integration-test”表示该Mojo默认被绑定在了pre-integration-test阶段。之后的:

      

    /**  
       * @parameter expression="${project}"  
       * @readonly  
       */  
      private MavenProject project;  

    表示该插件持有一个到MavenProject的引用,当客户方在执行该插件时,这里的project字段便表示客户工程。这里我们并没有对project进行初始化,但是“@parameter expression="${project}"”中的${project}即表示当前的客户工程,Maven在运行时会通过依赖注入自动将客户工程对象赋给project字段(请参考Maven自己的IoC容器Plexus)。此外,我们还声明了一个prefix字段,该字段表示对输出的各行加上prefix前缀字符串,默认为“+++”(加入prefix字段主要用于演示对插件参数的配置,这里的project和prefix都表示插件参数,我们可以在客户方重新配置这些参数)。

     

    由于上面的代码用到了MavenProject类,我们还需要在该插件工程的pom.xml中加入以下依赖:

           

    <dependency>  
               <groupId>org.apache.maven</groupId>  
               <artifactId>maven-project</artifactId>  
               <version>2.2.1</version>  
     </dependency>  

    在执行了“mvn clean install“之后,我们便可以通过一下命令调用该Mojo:

     

    mvn me.davenkin:demo-maven-plugin:1.0-SNAPSHOT:buildinfo

    笔者在当前的插件工程中执行该命令输出结果如下:

    ......
    
    ==========================
    
    Project build info:
    
    [INFO] +++   /home/davenkin/Desktop/demo-maven-plugin/demo-maven-pugin/target/classes
    
    [INFO] +++   /home/davenkin/Desktop/demo-maven-plugin/demo-maven-pugin/src/main/java
    
    [INFO] +++   /home/davenkin/Desktop/demo-maven-plugin/demo-maven-pugin/target/test-classes
    
    [INFO] +++   /home/davenkin/Desktop/demo-maven-plugin/demo-maven-pugin/src/test/java
    
    [INFO] =======================
    
    ......

    以上的”+++“便表示prefix的默认属性值,后跟各个build目录。我们也可以通过"-D"参数为prefix重新赋值:

     

    mvn me.davenkin:demo-maven-plugin:1.0-SNAPSHOT:buildinfo -Dbuildinfo.prefix=---

    以上我们用"---"代替了默认的"+++"。

     

    你可能注意到,为了调用该插件的buildinfo这个goal,我们需要给出该插件的所有坐标信息,包括groupId,artifactId和version号。你可能之前已经执行过"mvn eclipase:eclipase"或"mvn idea:idea"这样简洁的命令,让我们也来将自己的插件调用变简单一点。

     

    要通过简单别名的方式调用Maven插件,我们需要做到以下两点:

     

    1. 插件的artifactId应该遵循***-maven-plugin或maven-***-plugin命名规则,对于本文中的插件,我们已经遵循了。(当然不遵循也是可以的,此时你需要使用Maven Plugin Plugin来设置goalPrefix,此时就不见得为“demo”了)

    2. 需要将插件的groupId放在Maven默认的插件搜寻范围之内,默认情况下Maven只会在org.apache.maven.plugins和org.codehaus.mojo两个groupId下搜索插件,要让Maven同时搜索我们自己的groupId,我们需要在~/.m2/settings.xml中加入:

       

      <pluginGroups>  
             <pluginGroup>me.davenkin</pluginGroup>  
      </pluginGroups>

       

    在达到以上两点之后,我们便可以通过以下命令来调用自己的插件了:

     

    mvn demo:buildinfo

    (二)在别的项目使用插件

    要在别的项目中应用插件也是简单的,我们只需要在该项目的pom.xml文件中声明该插件的即可:

     

    <plugin>  
                  <groupId>me.davenkin</groupId>  
                  <artifactId>demo-maven-plugin</artifactId>  
                  <version>1.0-SNAPSHOT</version>  
                  <configuration>  
                      <prefix>---</prefix>  
                  </configuration>  
      
                  <executions>  
                      <execution>  
                          <id>buildinfo</id>  
                          <phase>process-sources</phase>  
                          <goals>  
                              <goal>buildinfo</goal>  
                          </goals>  
                      </execution>  
                  </executions>  
    </plugin>  

    在上面的配置中,我们将demo-maven-plugin插件的buildinfo绑定在了process-sources阶段,并将prefix参数该为了"---",这样在执行"mvn clean install" 时,该插件的输出内容将显示在终端。另外,我们可以通过设置属性的方式为demo-maven-plugin的prefix参数赋值,在pom.xml中加入一下property:

     

    <properties>  
           <buildinfo.prefix>---</buildinfo.prefix>  
    </properties>  

    此时,去掉plugin配置中的:

    <configuration>  
         <prefix>---</prefix>  
    </configuration>  

    运行"mvn clean install",输出效果和之前一样。

  • 相关阅读:
    论大型信息系统项目的范围管理
    算法分析与设计——回溯法实验报告
    算法分析与设计——贪心法实验报告
    算法分析与设计——动态规划法实验报告
    算法分析与设计——分治法实验报告
    机器学习与数据挖掘期末考试复习重点整理
    软件项目文档——Responsibility Assignment Matrix
    软件项目文档——Stakeholder Register
    在Eclipse中显示空格(space)和制表符(tab)
    Eclipse 每行 80 字符限制的提示线
  • 原文地址:https://www.cnblogs.com/davenkin/p/advanced-maven-write-your-own-plugin.html
Copyright © 2020-2023  润新知