java 简单代码生成器

本贴最后更新于 2759 天前,其中的信息可能已经时移世异
  • 一个简单的代码生成器实现。

  • 代码如下:
/** * 测试 * Created by GN on 2016/11/27. */ public class GnTest { @Test public void testGn() throws IOException { GnContext gnContext = new GnContext(); gnContext.put("domain","User"); gnContext.put("lowerDomain","user"); String path = "E:\\WorkSpace\\Idea\\ztx\\gn-cc\\src\\main\\resources\\DaoImpl.java"; Template template = GnUtil.getTemplate(path); String target = "G:\\DaoImpl.java"; File file = new File(target); template.merge(gnContext,file); } }
/** * 定义模板插入值 * Created by GN on 2016/11/27. */ public class GnContext { /** * 存储模板值 */ private Map<String, String> context = new HashMap<>(); public GnContext() { } public GnContext(Map<String, String> context) { this.context = context; } public void put(String key, String value) { context.put(key, value); } public String get(String key) { return context.get(key); } }
/** * Created by GN on 2016/11/27. */ public abstract class GnUtil { /** * 获取模板信息 * @param filePath 模板路径 * @return */ public static Template getTemplate(String filePath) throws IOException { if (!StringUtil.hasLength(filePath)){ throw new IllegalArgumentException("模板路径不能为空"); } File file = new File(filePath); if (!file.isFile() || !file.exists()){ throw new IllegalArgumentException("无法找到指定文件:"+filePath); } return new Template(file); } }
/** * 模板处理 * Created by GN on 2016/11/27. */ public class Template { private static final String TAG_PREFIX = "${"; private static final String TAG_POSTFIX = "}"; /** * 模板信息 */ private BufferedReader reader; private File file; /** * 模板标签,eg:${domain}:key=domain,value=${domain} */ private Map<String, String> tag = new HashMap<>(); public Template(File file) throws IOException { this.file = file; //初始化模板输入流 initReader(); } private void initReader() { if (file == null) { throw new IllegalArgumentException("获取模板失败"); } try { InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream(file), "UTF-8"); this.reader = new BufferedReader(inputStreamReader); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } /** * 处理标签到tag中 * * @param text */ private void initTag(String text) { if (!StringUtil.hasLength(text)) { return; } String tagFlag = getTagFlag(text); String tagText = getTagText(text); this.tag.put(tagText, tagFlag); //递归解析一行中的多个标签 int prefix = text.indexOf(TAG_PREFIX); String subText = text.substring(prefix + 2 + tagText.length()); if (hasTag(subText)) { initTag(subText); } } /** * 获取标签,${domain} * * @param text * @return */ private String getTagFlag(String text) { int prefix = text.indexOf(TAG_PREFIX); int postfix = text.indexOf(TAG_POSTFIX); return text.substring(prefix, postfix + 1); } /** * 获取标签中的内容,${domain} --> domain * * @param text * @return */ private String getTagText(String text) { String tagFlag = getTagFlag(text); return tagFlag.substring(2, tagFlag.length() - 1); } /** * 判断文本中是否含有标签 * * @param text * @return */ private boolean hasTag(String text) { if (!StringUtil.hasLength(text)) { return Boolean.FALSE; } return text.indexOf(TAG_PREFIX) > 0 && text.indexOf(TAG_POSTFIX) > 0; } /** * 生成模板 * * @param context 模板值定义 * @param target 目标生成文件 */ public void merge(GnContext context, File target) throws IOException { if (reader == null) { throw new IllegalArgumentException("读取模板失败"); } if (context == null) { throw new IllegalArgumentException("获取GnContext失败"); } if (target == null) { throw new IllegalArgumentException("获取输出流失败"); } String temp; FileWriter writer = new FileWriter(target, true); while ((temp = reader.readLine()) != null) { if (hasTag(temp)) { //解析出所有的标签 List<String> tagTextList = findTagTextList(temp); if (!tagTextList.isEmpty()) { for (String text : tagTextList) { String value = context.get(text); if (StringUtil.hasLength(value)){ temp = temp.replace(TAG_PREFIX + text + TAG_POSTFIX, value); } } } } writer.write(temp + "\n"); writer.flush(); } writer.close(); } /** * 获取文本中的标签 * * @param lineText * @return */ private List<String> findTagTextList(String lineText) { List<String> tagTextList = new ArrayList<>(); if (StringUtil.hasLength(lineText) && hasTag(lineText)) { String tmp = lineText; while (hasTag(tmp)) { String tagText = findTagText(tmp); if (!tagTextList.contains(tagText)) { tagTextList.add(tagText); } int begin = tmp.indexOf(tagText); tmp = tmp.substring(begin + tagText.length()+1); } } return tagTextList; } /** * 获取文本中的单个标签 * * @param text * @return */ private String findTagText(String text) { if (!StringUtil.hasLength(text)) { return null; } return getTagText(text); } }

  • 一下为测试使用模板 :
/** * Created by GNon 2016/9/8. */ @Service @Transactional public class ${domain}ServiceImpl implements I${domain}Service { @Autowired private ${domain}Dao dao; @Override public void save(${domain} ${lowerDomain}) { dao.save(${lowerDomain}); } @Override public void update(${domain} ${lowerDomain}) { dao.update(${lowerDomain}); } @Override public void delete(Serializable id) { dao.delete(id); } @Override public ${domain} findById(Serializable id) { return dao.findById(id); } @Override public List<${domain}> findAll() { return dao.findAll(); } @Override public PageData findListByPage(PageData pageData) { return dao.findListByPage(pageData); } }
  • 以下是通过上述代码实现的简单生成器
/** * 代码生成器 * Created by GN on 2016/11/28. */ public class GnCreator { /** * 实体 */ private List<String> domains = new ArrayList<>(); /** * 模板基础路径 */ private String baseTemplatePath = "E:\\WorkSpace\\demo\\src\\main\\resources\\"; /** * 生成文件保存基本路径 */ private String baseSavePath = "E:\\WorkSpace\\demosrc\\main\\java\\com\\gn\\demo\\"; /** * 模板 */ private List<String> templates = new ArrayList<>(); private final String DAOIMPL = "Dao.java"; private final String SERVICE = "Service.java"; private final String SERVICEIMPL = "ServiceImpl.java"; public GnCreator() { //初始化生成器信息 //初始化实体集合 String[] domainList = {"User"}; //如果实体很多,可以通过注解扫描的方式去获取,不用一个一个的去写 List<String> asList = Arrays.asList(domainList); domains.addAll(asList); //初始化模板 templates.add(DAOIMPL); templates.add(SERVICE); templates.add(SERVICEIMPL); } public void create() throws IOException { System.out.println("代码生成器开始执行>>>>>>>>>>>>>>>>>>>>"); for (String domain : domains) { System.out.println("开始生成实体【"+domain+"】代码..............."); //模板值定义 GnContext gnContext = new GnContext(); gnContext.put("domain",domain); gnContext.put("lowerDomain",domain.toLowerCase()); //根据模板生成代码 for (String tp : templates) { String templatePath = baseTemplatePath+tp; Template template = GnUtil.getTemplate(templatePath); //根据不同的模板保存到不同的目录 String targetFilePath = ""; String targetFileName = ""; if (tp.equals(DAOIMPL)){ targetFilePath = baseSavePath+"dao\\impl\\"; targetFileName = domain+DAOIMPL; }else if (tp.equals(SERVICE)){ targetFilePath = baseSavePath+"service\\"; targetFileName = "I"+domain+SERVICE; }else if (tp.equals(SERVICEIMPL)){ targetFilePath = baseSavePath + "service\\impl\\"; targetFileName = domain+SERVICEIMPL; } //判断目录是否存在,如果不存在则创建 File file = new File(targetFilePath); if (!file.exists()){ file.mkdirs(); } File targetFile = new File(targetFilePath+targetFileName); template.merge(gnContext,targetFile); } System.out.println("生成实体【"+domain+"】代码完成..............."); } System.out.println("代码生成器执行完毕>>>>>>>>>>>>>>>>>>>>>>>>"); } }

  • 以上为所有代码,仅为适用自己的需求,如果能帮助到其他人更好,说下简单思路:
    代码主要实现功能是获取模板中的 ${domain} ,然后通过替换的方式把传入的 GnContext 所对应的值,最终实现代码生成。替换一处我用的是直接查询替换,如果你愿意也可以用正则表达式去处理,这样也许会简洁很多。
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3202 引用 • 8217 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • ActiveMQ

    ActiveMQ 是 Apache 旗下的一款开源消息总线系统,它完整实现了 JMS 规范,是一个企业级的消息中间件。

    19 引用 • 13 回帖 • 683 关注
  • jsoup

    jsoup 是一款 Java 的 HTML 解析器,可直接解析某个 URL 地址、HTML 文本内容。它提供了一套非常省力的 API,可通过 DOM,CSS 以及类似于 jQuery 的操作方法来取出和操作数据。

    6 引用 • 1 回帖 • 496 关注
  • Redis

    Redis 是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API。从 2010 年 3 月 15 日起,Redis 的开发工作由 VMware 主持。从 2013 年 5 月开始,Redis 的开发由 Pivotal 赞助。

    284 引用 • 248 回帖
  • HHKB

    HHKB 是富士通的 Happy Hacking 系列电容键盘。电容键盘即无接点静电电容式键盘(Capacitive Keyboard)。

    5 引用 • 74 回帖 • 521 关注
  • 人工智能

    人工智能(Artificial Intelligence)是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门技术科学。

    115 引用 • 319 回帖
  • WebComponents

    Web Components 是 W3C 定义的标准,它给了前端开发者扩展浏览器标签的能力,可以方便地定制可复用组件,更好的进行模块化开发,解放了前端开发者的生产力。

    1 引用 • 15 关注
  • 负能量

    上帝为你关上了一扇门,然后就去睡觉了....努力不一定能成功,但不努力一定很轻松 (° ー °〃)

    89 引用 • 1251 回帖 • 393 关注
  • 旅游

    希望你我能在旅途中找到人生的下一站。

    100 引用 • 905 回帖
  • Elasticsearch

    Elasticsearch 是一个基于 Lucene 的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于 RESTful 接口。Elasticsearch 是用 Java 开发的,并作为 Apache 许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。

    117 引用 • 99 回帖 • 199 关注
  • OpenStack

    OpenStack 是一个云操作系统,通过数据中心可控制大型的计算、存储、网络等资源池。所有的管理通过前端界面管理员就可以完成,同样也可以通过 Web 接口让最终用户部署资源。

    10 引用 • 3 关注
  • Access
    1 引用 • 3 回帖 • 3 关注
  • MySQL

    MySQL 是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,目前属于 Oracle 公司。MySQL 是最流行的关系型数据库管理系统之一。

    694 引用 • 537 回帖 • 1 关注
  • 音乐

    你听到信仰的声音了么?

    62 引用 • 512 回帖
  • 面试

    面试造航母,上班拧螺丝。多面试,少加班。

    326 引用 • 1395 回帖
  • Bootstrap

    Bootstrap 是 Twitter 推出的一个用于前端开发的开源工具包。它由 Twitter 的设计师 Mark Otto 和 Jacob Thornton 合作开发,是一个 CSS / HTML 框架。

    18 引用 • 33 回帖 • 649 关注
  • 工具

    子曰:“工欲善其事,必先利其器。”

    300 引用 • 768 回帖
  • 职场

    找到自己的位置,萌新烦恼少。

    127 引用 • 1708 回帖 • 1 关注
  • SQLServer

    SQL Server 是由 [微软] 开发和推广的关系数据库管理系统(DBMS),它最初是由 微软、Sybase 和 Ashton-Tate 三家公司共同开发的,并于 1988 年推出了第一个 OS/2 版本。

    21 引用 • 31 回帖 • 1 关注
  • 宕机

    宕机,多指一些网站、游戏、网络应用等服务器一种区别于正常运行的状态,也叫“Down 机”、“当机”或“死机”。宕机状态不仅仅是指服务器“挂掉了”、“死机了”状态,也包括服务器假死、停用、关闭等一些原因而导致出现的不能够正常运行的状态。

    13 引用 • 82 回帖 • 78 关注
  • Quicker

    Quicker 您的指尖工具箱!操作更少,收获更多!

    37 引用 • 157 回帖 • 1 关注
  • 尊园地产

    昆明尊园房地产经纪有限公司,即:Kunming Zunyuan Property Agency Company Limited(简称“尊园地产”)于 2007 年 6 月开始筹备,2007 年 8 月 18 日正式成立,注册资本 200 万元,公司性质为股份经纪有限公司,主营业务为:代租、代售、代办产权过户、办理银行按揭、担保、抵押、评估等。

    1 引用 • 22 回帖 • 799 关注
  • Hexo

    Hexo 是一款快速、简洁且高效的博客框架,使用 Node.js 编写。

    22 引用 • 148 回帖 • 9 关注
  • Ant-Design

    Ant Design 是服务于企业级产品的设计体系,基于确定和自然的设计价值观上的模块化解决方案,让设计者和开发者专注于更好的用户体验。

    17 引用 • 23 回帖 • 3 关注
  • SVN

    SVN 是 Subversion 的简称,是一个开放源代码的版本控制系统,相较于 RCS、CVS,它采用了分支管理系统,它的设计目标就是取代 CVS。

    29 引用 • 98 回帖 • 698 关注
  • Kotlin

    Kotlin 是一种在 Java 虚拟机上运行的静态类型编程语言,由 JetBrains 设计开发并开源。Kotlin 可以编译成 Java 字节码,也可以编译成 JavaScript,方便在没有 JVM 的设备上运行。在 Google I/O 2017 中,Google 宣布 Kotlin 成为 Android 官方开发语言。

    19 引用 • 33 回帖 • 85 关注
  • Google

    Google(Google Inc.,NASDAQ:GOOG)是一家美国上市公司(公有股份公司),于 1998 年 9 月 7 日以私有股份公司的形式创立,设计并管理一个互联网搜索引擎。Google 公司的总部称作“Googleplex”,它位于加利福尼亚山景城。Google 目前被公认为是全球规模最大的搜索引擎,它提供了简单易用的免费服务。不作恶(Don't be evil)是谷歌公司的一项非正式的公司口号。

    49 引用 • 192 回帖
  • Hadoop

    Hadoop 是由 Apache 基金会所开发的一个分布式系统基础架构。用户可以在不了解分布式底层细节的情况下,开发分布式程序。充分利用集群的威力进行高速运算和存储。

    93 引用 • 122 回帖 • 616 关注