java工程自动生成的模板实现

背景

 九月份的最后一天抽空跟公司的java大神聊了会天,发现每天跟大神们聊天总能收获很多思路,想想接受了大神那么多的指点,就把他的一点小技巧分享出来。

 这次介绍的是JAVA 工程自动通过工具生成标准工程,按照指定步骤生成整个项目工程,解决每次新建项目工程相互拷贝的问题,我也是在用了一次以后发现这个功能很好,就去找原作者请教了一下,因而有了这篇文章用以致敬原作者。


效果展示

 我们使用的微服务是基于阿里开源的dubbo框架,整个项目的目录结构如下图所示。如下图中我们生成了一个promotion的dubbo项目工程,当然我们也可以生成其他额外的项目工程,只需要修改工程名字(如trade、member等)即可。只需执行命令:java -jar service-eve.jar app XXXX //xxxx 您的服务工程名字 比如:promotion member

img_05cba914933e886a0eeb80359e786801.png
工程目录结构

 通过反编译service-eve.jar了解了下内部是如何实现上述功能的,先看下整个功能实现的目录结构。

1、项目工程目录

img_e3bea0e29c240c22968af8c4ef06d593.png
工程自动生成模板

说明:

  • ServiceEve.java文件作为入口函数解析命令
  • template作为工程模板存在,内部是一个完整的dubbo工程项目
  • appServiceName作为关键字后面由希望生成的工程命令进行替换

2、模板内部java类实现

img_53070e1b05187d19f7ddda4782a80f7f.png
代码内容

说明:

  • java类内部的实现会涉及到项目的package名称,所以需要进行替换
  • 内部通过占位符${appServiceName}先占用,后期进行替换
  • java类的占位符通过velocity模板进行替换


代码实现

public class ServiceEve
{
  public static void main(String[] args)
    throws IOException
  {
    if ((args == null) || (args.length < 2))
    {
      System.exit(0);
    }

    if (args[0].equals("app"))
    {
      genServiceTemplate(args[1]);
    }
    else
    {
      System.exit(0);
    }
  }
  
  public static void genServiceTemplate(String appServcieName)
  {
    try
    {
      // 获取当前jar包的文件内容,因为整个模板在jar包的template目录当中
      JarFile jar = new JarFile("service-eve.jar");
      Enumeration<JarEntry> re = jar.entries();
      // 遍历jar包中的所有文件,针对在template目录下的文件进行处理
      while (re.hasMoreElements())
      {
        String name = ((JarEntry)re.nextElement()).getName();
        if (name.contains("template/")) {
          if (!name.endsWith("/"))
          {
            // 读取template目录下的文件,通过非/结尾来判断是否为文件
            List<String> lines = IOUtils.readLines(ServiceEve.class.getClassLoader().getResourceAsStream(name), "UTF-8");
            String targetFile = new File(".").getAbsolutePath() + "/" + name;
            // 替换appServiceName为项目工程名
            targetFile = targetFile.replaceAll("appServiceName", appServcieName);
            // 替换文件内容并写到文件当中
            merge(lines, targetFile, appServcieName);
          }
        }
      }
      System.out.println("done!");
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }
  }

  public static void merge(List<String> contents, String targetFile, String appServcieName)
  {
    try
    {
      // 文件的内容合并到StringBuffer当中
      StringBuffer sb = new StringBuffer();
      for (String content : contents) {
        sb.append(content).append("\n");
      }
      // 通过velocity模板引擎替换文件内容的占位符
      VelocityEngine ve = new VelocityEngine();
      ve.init();
      VelocityContext context = new VelocityContext();
      context.put("appServiceName", appServcieName);
      StringWriter writer = new StringWriter();
      // 模板引擎替换占位符,并将内容写入文件当中
      ve.evaluate(context, writer, "", sb.toString());
      FileUtils.writeStringToFile(new File(targetFile), writer.toString(), "UTF-8");
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }
  }

}

说明:

  • 源码实现中读取service-eve.jar并开始遍历模板工程/template目录
  • 第一步替换文件路径当中的appServiceName为新建项目的项目名
  • 第二步替换java源码文件中的占位符为新建项目的项目名
  • 核心思路在于读取jar包内容替换目录和内容,内容需要通过velocity引擎进行文本替换


结语

论java我很服海军,上述实现也是海军的杰作,让我也开了眼界

简介: 工程自动获取和封装用户自定义参数以及数据库表信息,并通过模板配置文件将生成代码文件直接输出到应用工程目录下,达到从数据库表到页面增删改查过程代码一键生成. 工程提供所有源码,包括第三方jar包也附带源码包 注意事项: 1.需要一定的java开发基础. 2.要有java开发的集成环境,本工程没有界面,很多功能都是通过直接注释,或增加一些代码完成. 3.JDK版本必须是1.6以上,否则会报版本错误.当然也可以更换工程依赖的jar,使用一些低版本的jar包 使用说明: 1. 修改数据库连接参数:详见jdbc.properties 2. 修改或增加数据库字段类型与编译语言数据类型映射:详见dm2java.properties 3. 修改模板配置信息:详见vm.xml 4. 编写用户模板,参考/templates目录下的文件 5. 开启关闭/备份: 调用FileUtilsExt.backup(String[] fileList, String backupDir)方法 6. 还原备份: 调用FileUtilsExt.recover(String backupDir)方法. 7. 从数据库表合成文件: 调用PlayTemplates的main方法 8. 从EXCEL和成文件: 调用ExcelUtils的main方法 详细说明: 1.自动封装用户参数 参数配置文件params.properties有三类参数: 1.1 以array.为前缀参数(可设定设定多个)且用逗号分隔,将封装成数组对象,可循环输出 例如: array.names=xixi, haha 模版调用: #foreach($item in $names) $item #end 输出:xixi haha 1.2 以single.为前缀的参数(可设定设定多个),可在模板中直接调用输出 例如: single.name=xixi 模版调用: $name 输出:xixi 1.3 无任何前缀的参数,为工程要强制使用的参数,必须填写 2. 封装数据库表参数,目前只支持达梦数据库(我们公司自个的数据库),其他数据库以后再完善 如果各位想用其他数据库,可以自己加载其他数据库的驱动,并修改一下DbOption类下的getTableColumns(String)方法中的查询表信息方法 以及添加类似dm2java.properties数据库类型到java数据类型的映射文件,不同数据库的方言和数据映射太烦了. 当然,也可以联系我^_^ 自动从数据库中获取表名/表注释/列名/列注释/列类型等等相关信息 示例:由角色表生成domain对象 模版: package $!{package}.domain; import java.util.Date; /** * $!system * @author $!author * @version $!version * @date $!dateTool.format('yyyy-MM-dd', ${date}) */ public class $!{tableAlias}{ #foreach($item in $columnList) private $!item.data_type $!item.column_name.toLowerCase(); // $!item.column_label #end #foreach($item in $columnList) #set($name = $!item.column_name.toLowerCase()) #set($upperName = $!{stringTool.firstUpperCase($name)}) public void set$!{upperName}($!item.data_type $name){ this.$name=$name; } public $
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值