Idea開發maven插件

場景描述

最近博主開發了一個用於接收數據的接口服務器,一開始數據是外部購買的,數據源只有一個地方,但是隨着業務的拓展,公司不打算全部數據都從外部購買,而是將其中一部分數據交給公司爬蟲部門來爬取,這樣數據源變成了兩處。但是博主的接口服務器還有一個監控模塊,主要是用來實時展示數據進來的詳情,正是由於監控模塊的存在,對應不同的數據源博主還得改源碼來滿足不同的需求,這樣一來就很坑了,如果每次新增個數據源我都要做個自定義的那得多麻煩,於是乎博主在分析整個架構後,將代碼做了重構,最後重構的情況就是生成一個常量類,每次爭對不同的數據源,將常量類裏面對應的常量註釋掉即可。這下操作起來就方便多了,每次來個新的數據源,博主只需要新增常量並將其它的常量註釋掉即可。由於前面都是開發階段,博主想怎麼整都可以,但是後面進入了流程化階段了,項目需要交給配置管理組管理,打包發佈什麼的都是由配置管理組來負責,但是前面博主說了,對不同數據源博主需要註釋常量類裏面的一些字段來打包,但是項目交給配管組後,配管組是沒權限該代碼了,這就很尷尬了,博主的小聰明在這裏就行不通了。於是乎,博主又開始耍小聰明瞭,能不能讓配置組打包的時候加個參數什麼的來實現對常量類的修改,博主找遍了整個互聯網都沒找到這樣的插件(或者說操作簡單,兼容性好的插件),所以博主打算自己開發一個maven插件。

插件功能

通過mvn指令傳遞參數來實現打包前修改項目源碼。

插件開發

第一步:創建插件項目

IDEA新建一個maven項目,注意選擇maven-archetype-mojo這個模板
在這裏插入圖片描述

第二步:插件實現

沒錯,就是這麼簡單,只要兩步,因爲你在選擇好模板創建項目後,idea已經自動加入了一些依賴,並生成一個mojo類,該類繼承自AbstractMojo。該類裏面有一個execute方法,execute是程序的主入口。

2.1 聲明mojo類(插件)

有兩種方式聲明一個類是mojo類,一種是通過文檔註解的方式,如下所示:

/**
* @goal ChangeConstant
*/

另外一種是通過添加@Mojo(name = “ChangeConstant”)註解的方式來聲明,註解方式需要加依賴:

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

goal的作用後面會說明

2.2 添加參數

在使用maven插件的時候,有時需要傳遞一些參數,參數功能可以通過文檔註釋或者註解來聲明。比如我要傳遞一個文件路徑的參數,這裏使用註解來聲明:

@Parameter( property = "ChangeConstant.filePath", defaultValue = "filePath default" )
 private String filePath;

2.3 execut方法實現自定義插件功能

這裏博主希望在打包前對常量類做修改,常量類如下,如果是內部源,則將對外監控那四個常量註釋掉,如果是對外監控,則將內部監控那四個常量註釋掉。

    //對外監控
//    public static final String logrecord = "logrecord";
//    public static final String usrbyzqsjyb = "usrbyzqsjyb";
//    public static final String usrbyzxsltj = "usrbyzxsltj";
//    public static final String usrbyzxxq = "usrbyzxxq";


    //內部監控
    public static final String logrecord = "logrecord_inner";
    public static final String usrbyzqsjyb = "usrbyzqsjyb_inner";
    public static final String usrbyzxsltj = "usrbyzxsltj_inner";
    public static final String usrbyzxxq = "usrbyzxxq_inner";

修改文件就不詳敘了,大體思路就是讀進來->修改->寫入。下面是博主的插件類源碼:

package com.riclee;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;

import java.io.*;

/**
 * author: lichao
 * date: 2019/04/08
 */
@Mojo(name = "ChangeConstant")
public class ChangeConstantMojo extends AbstractMojo
{
    @Parameter( property = "ChangeConstant.project", defaultValue = "${project}" )
    private MavenProject project;


    @Parameter( property = "ChangeConstant.filePath", defaultValue = "filePath default" )
    private String filePath;


    @Parameter( property = "ChangeConstant.type", defaultValue = "bydata" )
    private String type;

    public void execute()
        throws MojoExecutionException
    {
        filePath = project.getBasedir() + filePath;
        //根據操作系統類型,修改目錄分隔符
        if(File.separator.equals("/")){
            filePath = filePath.replaceAll("\\\\","/");
        }else if(File.separator.equals("\\")){
            filePath = filePath.replaceAll("[/]","\\\\");
        }
        getLog().info("filePath = " + filePath);
        if(type.equals("bydata")){
            getLog().info("type = " + type + ", 對外接口服務" );
        }else if(type.equals("innerdata")){
            getLog().info("type = " + type + ", 內部採集接口服務" );
        }
        try{
            FileReader fr = new FileReader(filePath);
            BufferedReader bfr = new BufferedReader(fr);
            String line = null;
            StringBuffer newContent = new StringBuffer();
            while((line = bfr.readLine())!=null){
                if(type.equals("bydata")){
                    if(line.contains("logrecord")){
                        lineChange(line,newContent);
                    }else if(line.contains("usrbyzqsjyb")){
                        lineChange(line,newContent);
                    }else if(line.contains("usrbyzxsltj")){
                        lineChange(line,newContent);
                    }else if(line.contains("usrbyzxxq")){
                        lineChange(line,newContent);
                    }else{
                        newContent.append(line + System.lineSeparator());
                    }
                }

                if(type.equals("innerdata")){
                    if(line.contains("logrecord")){
                        lineChange2(line,newContent);
                    }else if(line.contains("usrbyzqsjyb")){
                        lineChange2(line,newContent);
                    }else if(line.contains("usrbyzxsltj")){
                        lineChange2(line,newContent);
                    }else if(line.contains("usrbyzxxq")){
                        lineChange2(line,newContent);
                    }else{
                        newContent.append(line + System.lineSeparator());
                    }
                }
            }
            fr.close();
            bfr.close();

            BufferedWriter bfw = new BufferedWriter(new FileWriter(filePath));
            bfw.write(newContent.toString());
            bfw.close();
        }catch (IOException e){
            e.printStackTrace();
        }

    }

    public void lineChange(String line,StringBuffer sb){
        if(line.contains("inner")){
            if(!line.contains("//")){
                sb.append("//" + line + System.lineSeparator());
            }else{
                sb.append(line + System.lineSeparator());
            }
        }else{
            sb.append(line.replaceAll("//","") + System.lineSeparator());
        }
    }


    public void lineChange2(String line,StringBuffer sb){
        if(line.contains("inner")){
            sb.append(line.replaceAll("//","") + System.lineSeparator());
        }else{
            if(!line.contains("//")){
                sb.append("//" + line + System.lineSeparator());
            }else{
                sb.append(line + System.lineSeparator());
            }
        }
    }
}

Pom依賴

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.riclee</groupId>
  <artifactId>change-constant-maven-plugin</artifactId>
  <packaging>maven-plugin</packaging>
  <version>1.0.0</version>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
          <source>1.7</source>
          <target>1.7</target>
        </configuration>
      </plugin>
    </plugins>
  </build>
  <name>change-constant-maven-plugin Maven Mojo</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>org.apache.maven</groupId>
      <artifactId>maven-plugin-api</artifactId>
      <version>2.0</version>
    </dependency>
    <dependency>
      <groupId>org.apache.maven.plugin-tools</groupId>
      <artifactId>maven-plugin-annotations</artifactId>
      <version>3.4</version>
    </dependency>
    <dependency>
      <groupId>org.apache.maven</groupId>
      <artifactId>maven-project</artifactId>
      <version>2.2.1</version>
    </dependency>
  </dependencies>
</project>

2.4插件使用

插件開發好後install一下,提交到倉庫中,根據你所配置的座標地址,在項目中引用

		<plugins>
			<plugin>
				<groupId>com.gildata</groupId>
				<artifactId>change-constant-maven-plugin</artifactId>
				<version>1.0.1</version>
				<executions>
					<execution>
						<id>ChangeConstant</id>
						<phase>pre-clean</phase>
						<goals>
							<goal>ChangeConstant</goal>
						</goals>
					</execution>
				</executions>
			</plugin>
		</plugins>

其中phase是指定你要在哪個生命週期使用插件,goal就是@mojo註解中的值。
前面在開發插件的時候添加過一些參數,這些參數也可以在pom文件中指定默認值。

		<properties>
			<spring.profiles.active>dev</spring.profiles.active>
			<ChangeConstant.filePath>\src\main\java\com\gildata\byinterserver\constant\Constant.java</ChangeConstant.filePath>
			<ChangeConstant.type>bydata</ChangeConstant.type>
		</properties>

在打包的時候可以動態指定參數的值來覆蓋默認值

mvn -DChangeConstant.type=innerdata clean package

以上只是博主的拋磚引玉,maven插件更詳細的使用可以參考文檔:
https://maven.apache.org/guides/introduction/introduction-to-plugins.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章