maven插件你了解吗?自己写过maven插件吗?

简介: maven插件你了解吗?自己写过maven插件吗?
前几天工作之余,同事让我写一个Maven插件,因为项目很多很杂,我们公司又没有专业的数据库字典管理工具,都是我们开发人员用Excel整理一个数据字典给我们现场实施人员,每次增加新功能或该需求,增加表和修改数据时,对Excel形式数据字典维护有点。。。,此文不是讲如何维护Excel而是手写maven插件,对于我需要的功能用Maven插件来实现太简单了。

那就开始。

这里只介绍用IDEA的做法,当然其他工具也可以,只是我这边用的是IDEA。首先我们先建个mavn项目如图:

640.png
这里就是为什么我选着IDEA因为IDEA有现成的工具

然后就是填写GroupId和Version
640.png
再然后就是完成

640.png
打开项目
640.png
已经有了现成的例子了,我们就在它给的例子上做修改。

参考maven官网添加依赖以及插件


    <!-- plugin API and plugin-tools -->
    <dependency>
      <groupId>org.apache.maven</groupId>
      <artifactId>maven-plugin-api</artifactId>
      <version>3.5.2</version>
    </dependency>
    <dependency>
      <groupId>org.apache.maven.plugin-tools</groupId>
      <artifactId>maven-plugin-annotations</artifactId>
      <version>3.5</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>easyexcel</artifactId>
      <version>2.1.6</version>
    </dependency>
    <!-- 用于获取jpa注解生成对应的excel-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-jpa</artifactId>
      <version>2.2.4.RELEASE</version>
    </dependency>

  </dependencies>

  <build>
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.7.0</version>
      </plugin>
      <plugin>
        <artifactId>maven-install-plugin</artifactId>
        <version>2.5.2</version>
      </plugin>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-plugin-plugin</artifactId>
        <version>3.5.1</version>
      </plugin>
    </plugins>
  </build>

配置算是结束了

先建类注解和属性注解两个注解类

类注解

/**
 * @author zhuyao
 * @description 类注解获取表名
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TableName {

    /**
     * 名称
     * @return
     */
    String name() default "";

    /**
     * 信息
     * @return
     */
    String message();
}

/**
 * @author zhuyao
 * @description 属性注解用于获取表字段意思
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface FieldName {

    /**
     * 名称
     * @return
     */
    String name() default "";

    /**
     * 信息
     * @return
     */
    String message();
}

然后上逻辑代码


/**
 * @author zhuyao
 */
@Mojo(name = "tableToExcelMaven")//这里到引用插件的时候需要用到
public class TableToExcelMavenMojo extends AbstractMojo {
    /**
     * 扫描包
     */
    @Parameter(property = "scanPackage",defaultValue = "")
    private String scanPackage;
    /**
     * 项目源码包路径
     */
    @Parameter(defaultValue = "${project.compileClasspathElements}", readonly = true)
    private String[] compileClasspathElements;
    /**
     * 项目的artifactId
     */
    @Parameter(defaultValue = "${project.artifactId}", readonly = true)
    private String artifactId;
    private URLClassLoader loader;

    public void execute() {
        String file = compileClasspathElements[0].replace("classes","");
        String classPath = compileClasspathElements[0];
        String libPath = compileClasspathElements[0].replace("classes",artifactId+"/WEB-INF/lib");
        String basePackage = compileClasspathElements[0]+"/"+scanPackage.replaceAll("\\.","/");

        try {
            String libDir = (new URL("file",null,new File(libPath).getCanonicalPath()+File.separator)).toString();
            String baseDir = (new URL("file",null,new File(classPath).getCanonicalPath()+File.separator)).toString();

            File libDirFile = new File(libDir.replaceAll("file",""));
            URLStreamHandler us = null;
            List<URL> libs = new ArrayList<URL>();
            if (null!=libDirFile.listFiles()){
                for (File jar : libDirFile.listFiles()) {
                    libs.add(new URL(null,libDir+jar.getName(),us));
                }
            }
            libs.add(new URL(null,baseDir,us));
            loader = new URLClassLoader(libs.toArray(new URL[libs.size()]),Thread.currentThread().getContextClassLoader());
            File dir = new File(basePackage);
            List<Class<?>> classes = new ArrayList<Class<?>>();
            scanner(classes,dir,classPath);

            List<List<Object>> objectList = new ArrayList<List<Object>>();
            for (Class<?> aClass : classes) {
                if ((aClass.getAnnotation(TableName.class) != null) || (aClass.getAnnotation(Table.class) != null) || (aClass.getAnnotation(Entity.class)!=null)) {
                    List<Object> list1 = new ArrayList<Object>();
                    List<Object> list2 = new ArrayList<Object>();
                    List<Object> list3 = new ArrayList<Object>();
                    list1.add("表字段");
                    if ((aClass.getAnnotation(TableName.class) != null) && isNotEmpty(aClass.getAnnotation(TableName.class).name())){
                        list1.add(aClass.getAnnotation(TableName.class).name());
                    }else if ((aClass.getAnnotation(Table.class) != null) && isNotEmpty(aClass.getAnnotation(Table.class).name())){
                        list1.add(aClass.getAnnotation(Table.class).name());
                    } else {
                        list1.add(aClass.getSimpleName().toLowerCase());
                    }
                    list2.add("字段意思");
                    if ((aClass.getAnnotation(TableName.class) != null) && isNotEmpty(aClass.getAnnotation(TableName.class).message())){
                        list2.add(aClass.getAnnotation(TableName.class).message());
                    } else {
                        list2.add("未写注释");
                    }

                    list3.add("");
                    Field[] declaredFields = aClass.getDeclaredFields();
                    for (Field declaredField : declaredFields) {
                        if ((declaredField.getAnnotation(FieldName.class) != null) || (declaredField.getAnnotation(Column.class) != null)) {
                            if ((declaredField.getAnnotation(FieldName.class) != null) && isNotEmpty(declaredField.getAnnotation(FieldName.class).name())){
                                list1.add(declaredField.getAnnotation(FieldName.class).name());
                            }else if ((declaredField.getAnnotation(Column.class) != null) && isNotEmpty(declaredField.getAnnotation(Column.class).name())){
                                list1.add(declaredField.getAnnotation(Column.class).name());
                            }else {
                                list1.add(apply(declaredField.getName()));
                            }
                            if ((declaredField.getAnnotation(FieldName.class) != null)&& isNotEmpty(declaredField.getAnnotation(FieldName.class).message())){
                                list2.add(declaredField.getAnnotation(FieldName.class).message());
                            } else {
                                list2.add("未写注释");
                            }
                        }else {
                            list1.add(apply(declaredField.getName()));
                            list2.add("未写注释");
                        }

                    }
                    objectList.add(list1);
                    objectList.add(list2);
                    objectList.add(list3);
                }

                OutputStream out = new FileOutputStream(file + "/table.xlsx");

                new ExcelWriterBuilder().excelType(ExcelTypeEnum.XLSX)
                        .file(out)
                        .sheet(1,"表").table(1)
                        .doWrite(objectList);
                out.close();

            }
        } catch (IOException e){
            e.fillInStackTrace();
        }
    }

    private void scanner(List<Class<?>> classes,File dir,String classPath){
        File[] files = dir.listFiles();
        for (File file : files) {
            if (file.isDirectory()){
                scanner(classes,file,classPath);
            }else {
                if (!file.getName().endsWith(".class")){
                    continue;
                }
                String path = file.getPath();
                String className = getClassName(path,classPath);
                try {
                    classes.add(Class.forName(className,true,loader));
                } catch (ClassNotFoundException e){
                    e.printStackTrace();
                    continue;
                }
            }
        }
    }

    private String getClassName(String path,String classPath){
        classPath = (classPath==null?"":classPath);
        String classDir = path.replaceAll("\\\\", "/")
                .replaceAll(classPath.replaceAll("\\\\", "/"), "")
                .replaceAll("/", ".")
                .replaceAll("\\.class", "");
        String className = classDir.substring(1, classDir.length());
        return className;
    }

    /**
     * jpa源码中的实体类如何转成数据库字段
     * @param name
     * @return
     */
    private static String apply(String name) {
        if (name == null) {
            return null;
        } else {
            StringBuilder builder = new StringBuilder(name.replace('.', '_'));

            for(int i = 1; i < builder.length() - 1; ++i) {
                if (isUnderscoreRequired(builder.charAt(i - 1), builder.charAt(i), builder.charAt(i + 1))) {
                    builder.insert(i++, '_');
                }
            }
            return builder.toString().toLowerCase();
        }
    }

    private static boolean isUnderscoreRequired(char before, char current, char after) {
        return Character.isLowerCase(before) && Character.isUpperCase(current) && Character.isLowerCase(after);
    }
}

到这项目需要的maven插件已经算是结束了,现在就是把它打包到中央仓库,如果你不分享给其他用只要把它放到自己的本地仓库就行了,mvn install

现在我们测试下

在项目中引入jar包和插件

<dependencies>
        <dependency>
            <groupId>xin.zhuyao</groupId>
            <artifactId>table-to-excel-maven</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>xin.zhuyao</groupId>
                <artifactId>table-to-excel-maven</artifactId>
                <version>1.0-SNAPSHOT</version>
                <configuration>
                    <!--扫描包-->
                    <scanPackage>xin.zhuyao.wechat_article</scanPackage>
                </configuration>
                <executions>
                    <execution>
                        <id>tableToExcelMaven</id>
                        <phase>prepare-package</phase>
                        <goals>
                            <!--这个就是Mojo的name-->
                            <goal>tableToExcelMaven</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

这个插件是在打包时执行
640.png
这个项目用的是spring-data-jpa写的所以没有添加我的注解也是可以生产表格的。

640.png
640.png
现在我加上注解

640.png
打包后的得到道德excel是
640.png

这就出来了,也就是每次你在修改添加数据库实体类的时候添加注解就可以了,每次都会生成新的。是不是很神奇。其实maven插件还有更多用处,跟多方法,你可以去官网查查:http://maven.apache.org/plugins/上面的项目地址在:https://github.com/zywaiting/table-to-excel-maven 学习永远是自己的事,别人说了再多,自己不动手也是学不到太多东西,maven插件官网已给,项目地址已给,剩下的就靠你自己了,其实我写的连这个知识点的九牛一毛都不算,在写这篇文章时我才发现,自己真的太渺小了。
相关文章
|
Java 应用服务中间件 Apache
Maven程序 tomcat插件安装与web工程启动
Maven程序 tomcat插件安装与web工程启动
188 0
|
XML Java Maven
maven总结三: 常用插件
maven总结三: 常用插件
225 3
|
10月前
|
缓存 Java Maven
【简单四步教你解决♥十分有效】Maven依赖报错、依赖或插件导入失败的万能解决办法
【简单四步教你解决♥十分有效】Maven依赖报错、依赖或插件导入失败的万能解决办法!在处理Maven项目问题时,首先检查Maven配置是否正确。接着通过“File--Invalidata Caches”清除IDEA缓存并重启。使用Maven命令`mvn dependency:purge-local-repository`和`mvn dependency:resolve`清除本地依赖缓存。最后,在Terminal中输入`mvn clean install`完成构建。
2914 1
【简单四步教你解决♥十分有效】Maven依赖报错、依赖或插件导入失败的万能解决办法
|
Java 测试技术 Maven
Maven 插件
Maven包含clean、default(build)、site三大生命周期,分别处理项目清理、部署和文档创建。每个生命周期由多个阶段组成,充当标准化接口,实际工作由插件执行。例如,`mvn clean`调用的是clean生命周期的clean阶段,其实现由maven-clean-plugin插件完成。Maven是一个依赖插件的框架,插件负责任务如生成jar/war、编译、测试、文档和报告。通过`mvn plugin-name:goal-name`命令执行插件目标。
|
10月前
|
存储 Java Linux
【Maven】——基础入门,插件安装、配置和简单使用,Maven如何设置国内源
Maven插件安装,Maven项目构建,依赖管理,Haven Help插件,Maven仓库,Maven如何设置国内源
|
12月前
|
Java 编译器 测试技术
全面理解Maven Compiler Plugin-Maven编译插件
【10月更文挑战第16天】
2619 1
|
Java Maven Spring
Maven重打包问题之maven-shade-plugin插件对于重复的class文件会如何处理
Maven重打包问题之maven-shade-plugin插件对于重复的class文件会如何处理
306 2
|
Java Maven
idea安装并使用maven依赖分析插件:Maven Helper
idea安装并使用maven依赖分析插件:Maven Helper
4169 7
|
数据可视化 Java 程序员
IDEA插件-Maven Helper
Maven Helper是一个用于Apache Maven项目的IntelliJ IDEA插件,它提供了一些有用的功能来帮助开发人员更好地管理和调试Maven项目。
1447 0
IDEA插件-Maven Helper
|
Java jenkins 持续交付
jenkins学习笔记之十七:使用插件及maven上传制品到nexus
jenkins学习笔记之十七:使用插件及maven上传制品到nexus