java 简单代码生成器

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

  • 代码如下:
/** * 测试 * 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 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3200 引用 • 8216 回帖

相关帖子

欢迎来到这里!

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

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

推荐标签 标签

  • C++

    C++ 是在 C 语言的基础上开发的一种通用编程语言,应用广泛。C++ 支持多种编程范式,面向对象编程、泛型编程和过程化编程。

    107 引用 • 153 回帖
  • 负能量

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

    89 引用 • 1251 回帖 • 407 关注
  • Solo

    Solo 是一款小而美的开源博客系统,专为程序员设计。Solo 有着非常活跃的社区,可将文章作为帖子推送到社区,来自社区的回帖将作为博客评论进行联动(具体细节请浏览 B3log 构思 - 分布式社区网络)。

    这是一种全新的网络社区体验,让热爱记录和分享的你不再感到孤单!

    1441 引用 • 10069 回帖 • 495 关注
  • Vim

    Vim 是类 UNIX 系统文本编辑器 Vi 的加强版本,加入了更多特性来帮助编辑源代码。Vim 的部分增强功能包括文件比较(vimdiff)、语法高亮、全面的帮助系统、本地脚本(Vimscript)和便于选择的可视化模式。

    29 引用 • 66 回帖 • 1 关注
  • GitHub

    GitHub 于 2008 年上线,目前,除了 Git 代码仓库托管及基本的 Web 管理界面以外,还提供了订阅、讨论组、文本渲染、在线文件编辑器、协作图谱(报表)、代码片段分享(Gist)等功能。正因为这些功能所提供的便利,又经过长期的积累,GitHub 的用户活跃度很高,在开源世界里享有深远的声望,并形成了社交化编程文化(Social Coding)。

    210 引用 • 2040 回帖
  • BookxNote

    BookxNote 是一款全新的电子书学习工具,助力您的学习与思考,让您的大脑更高效的记忆。

    笔记整理交给我,一心只读圣贤书。

    1 引用 • 1 回帖 • 2 关注
  • sts
    2 引用 • 2 回帖 • 227 关注
  • 域名

    域名(Domain Name),简称域名、网域,是由一串用点分隔的名字组成的 Internet 上某一台计算机或计算机组的名称,用于在数据传输时标识计算机的电子方位(有时也指地理位置)。

    43 引用 • 208 回帖
  • 设计模式

    设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。

    200 引用 • 120 回帖
  • HTML

    HTML5 是 HTML 下一个的主要修订版本,现在仍处于发展阶段。广义论及 HTML5 时,实际指的是包括 HTML、CSS 和 JavaScript 在内的一套技术组合。

    108 引用 • 295 回帖 • 1 关注
  • Facebook

    Facebook 是一个联系朋友的社交工具。大家可以通过它和朋友、同事、同学以及周围的人保持互动交流,分享无限上传的图片,发布链接和视频,更可以增进对朋友的了解。

    4 引用 • 15 回帖 • 447 关注
  • 支付宝

    支付宝是全球领先的独立第三方支付平台,致力于为广大用户提供安全快速的电子支付/网上支付/安全支付/手机支付体验,及转账收款/水电煤缴费/信用卡还款/AA 收款等生活服务应用。

    29 引用 • 347 回帖 • 1 关注
  • SQLite

    SQLite 是一个进程内的库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。SQLite 是全世界使用最为广泛的数据库引擎。

    5 引用 • 7 回帖 • 1 关注
  • gRpc
    11 引用 • 9 回帖 • 91 关注
  • MongoDB

    MongoDB(来自于英文单词“Humongous”,中文含义为“庞大”)是一个基于分布式文件存储的数据库,由 C++ 语言编写。旨在为应用提供可扩展的高性能数据存储解决方案。MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似 JSON 的 BSON 格式,因此可以存储比较复杂的数据类型。

    91 引用 • 59 回帖 • 4 关注
  • 前端

    前端技术一般分为前端设计和前端开发,前端设计可以理解为网站的视觉设计,前端开发则是网站的前台代码实现,包括 HTML、CSS 以及 JavaScript 等。

    245 引用 • 1338 回帖 • 1 关注
  • Oracle

    Oracle(甲骨文)公司,全称甲骨文股份有限公司(甲骨文软件系统有限公司),是全球最大的企业级软件公司,总部位于美国加利福尼亚州的红木滩。1989 年正式进入中国市场。2013 年,甲骨文已超越 IBM,成为继 Microsoft 后全球第二大软件公司。

    107 引用 • 127 回帖 • 340 关注
  • Sillot

    Insights(注意当前设置 master 为默认分支)

    汐洛彖夲肜矩阵(Sillot T☳Converbenk Matrix),致力于服务智慧新彖乄,具有彖乄驱动、极致优雅、开发者友好的特点。其中汐洛绞架(Sillot-Gibbet)基于自思源笔记(siyuan-note),前身是思源笔记汐洛版(更早是思源笔记汐洛分支),是智慧新录乄终端(多端融合,移动端优先)。

    主仓库地址:Hi-Windom/Sillot

    文档地址:sillot.db.sc.cn

    注意事项:

    1. ⚠️ 汐洛仍在早期开发阶段,尚不稳定
    2. ⚠️ 汐洛并非面向普通用户设计,使用前请了解风险
    3. ⚠️ 汐洛绞架基于思源笔记,开发者尽最大努力与思源笔记保持兼容,但无法实现 100% 兼容
    29 引用 • 25 回帖 • 117 关注
  • jQuery

    jQuery 是一套跨浏览器的 JavaScript 库,强化 HTML 与 JavaScript 之间的操作。由 John Resig 在 2006 年 1 月的 BarCamp NYC 上释出第一个版本。全球约有 28% 的网站使用 jQuery,是非常受欢迎的 JavaScript 库。

    63 引用 • 134 回帖 • 735 关注
  • DNSPod

    DNSPod 建立于 2006 年 3 月份,是一款免费智能 DNS 产品。 DNSPod 可以为同时有电信、网通、教育网服务器的网站提供智能的解析,让电信用户访问电信的服务器,网通的用户访问网通的服务器,教育网的用户访问教育网的服务器,达到互联互通的效果。

    6 引用 • 26 回帖 • 530 关注
  • Notion

    Notion - The all-in-one workspace for your notes, tasks, wikis, and databases.

    10 引用 • 77 回帖 • 1 关注
  • B3log

    B3log 是一个开源组织,名字来源于“Bulletin Board Blog”缩写,目标是将独立博客与论坛结合,形成一种新的网络社区体验,详细请看 B3log 构思。目前 B3log 已经开源了多款产品:SymSoloVditor思源笔记

    1063 引用 • 3455 回帖 • 162 关注
  • 大疆创新

    深圳市大疆创新科技有限公司(DJI-Innovations,简称 DJI),成立于 2006 年,是全球领先的无人飞行器控制系统及无人机解决方案的研发和生产商,客户遍布全球 100 多个国家。通过持续的创新,大疆致力于为无人机工业、行业用户以及专业航拍应用提供性能最强、体验最佳的革命性智能飞控产品和解决方案。

    2 引用 • 14 回帖
  • flomo

    flomo 是新一代 「卡片笔记」 ,专注在碎片化时代,促进你的记录,帮你积累更多知识资产。

    6 引用 • 141 回帖 • 1 关注
  • Windows

    Microsoft Windows 是美国微软公司研发的一套操作系统,它问世于 1985 年,起初仅仅是 Microsoft-DOS 模拟环境,后续的系统版本由于微软不断的更新升级,不但易用,也慢慢的成为家家户户人们最喜爱的操作系统。

    227 引用 • 476 回帖
  • 运维

    互联网运维工作,以服务为中心,以稳定、安全、高效为三个基本点,确保公司的互联网业务能够 7×24 小时为用户提供高质量的服务。

    150 引用 • 257 回帖 • 1 关注
  • 阿里巴巴

    阿里巴巴网络技术有限公司(简称:阿里巴巴集团)是以曾担任英语教师的马云为首的 18 人,于 1999 年在中国杭州创立,他们相信互联网能够创造公平的竞争环境,让小企业通过创新与科技扩展业务,并在参与国内或全球市场竞争时处于更有利的位置。

    43 引用 • 221 回帖 • 63 关注