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("\n==========================\nProject build info:");  
       String[] info = {outputDirectory, sourceDirectory, testOutputDirectory, testSourceDirectory};  
       for (String item : info) {  
           getLog().info("\t" + 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",輸出效果和之前一樣。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM