Idea开发maven插件

时间:2022-07-23
本文章向大家介绍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>srcmainjavacomgildatabyinterserverconstantConstant.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