前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >maven插件你了解吗?自己写过maven插件吗?

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

作者头像
用户2242639
发布2023-12-26 11:49:20
1380
发布2023-12-26 11:49:20
举报
文章被收录于专栏:Java经验总结Java经验总结

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

那就开始。

这里只介绍用IDEA的做法,当然其他工具也可以,只是我这边用的是IDEA。

首先我们先建个mavn项目如图:

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

然后就是填写GroupId和Version

再然后就是完成

打开项目

已经有了现成的例子了,我们就在它给的例子上做修改。

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

代码语言:javascript
复制
    <!-- 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>

配置算是结束了

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

类注解

代码语言:javascript
复制
/**
 * @author zhuyao
 * @description 类注解获取表名
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TableName {

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

    /**
     * 信息
     * @return
     */
    String message();
}
代码语言:javascript
复制
/**
 * @author zhuyao
 * @description 属性注解用于获取表字段意思
 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface FieldName {

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

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

然后上逻辑代码

代码语言:javascript
复制
/**
 * @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包和插件

代码语言:javascript
复制
<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>

这个插件是在打包时执行

这个项目用的是spring-data-jpa写的所以没有添加我的注解也是可以生产表格的。

现在我加上注解

打包后的得到道德excel是

这就出来了,也就是每次你在修改添加数据库实体类的时候添加注解就可以了,每次都会生成新的。是不是很神奇。其实maven插件还有更多用处,跟多方法,你可以去官网查查:http://maven.apache.org/plugins/

上面的项目地址在:https://github.com/zywaiting/table-to-excel-maven

学习永远是自己的事,别人说了再多,自己不动手也是学不到太多东西,maven插件官网已给,项目地址已给,剩下的就靠你自己了,其实我写的连这个知识点的九牛一毛都不算,在写这篇文章时我才发现,自己真的太渺小了。

(完)

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2023-12-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java经验总结 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档