java 简单代码生成器

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

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

    3203 引用 • 8217 回帖

相关帖子

欢迎来到这里!

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

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

推荐标签 标签

  • IBM

    IBM(国际商业机器公司)或万国商业机器公司,简称 IBM(International Business Machines Corporation),总公司在纽约州阿蒙克市。1911 年托马斯·沃森创立于美国,是全球最大的信息技术和业务解决方案公司,拥有全球雇员 30 多万人,业务遍及 160 多个国家和地区。

    17 引用 • 53 回帖 • 148 关注
  • 百度

    百度(Nasdaq:BIDU)是全球最大的中文搜索引擎、最大的中文网站。2000 年 1 月由李彦宏创立于北京中关村,致力于向人们提供“简单,可依赖”的信息获取方式。“百度”二字源于中国宋朝词人辛弃疾的《青玉案·元夕》词句“众里寻他千百度”,象征着百度对中文信息检索技术的执著追求。

    63 引用 • 785 回帖 • 68 关注
  • Jenkins

    Jenkins 是一套开源的持续集成工具。它提供了非常丰富的插件,让构建、部署、自动化集成项目变得简单易用。

    54 引用 • 37 回帖 • 2 关注
  • WebComponents

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

    1 引用 • 13 关注
  • 机器学习

    机器学习(Machine Learning)是一门多领域交叉学科,涉及概率论、统计学、逼近论、凸分析、算法复杂度理论等多门学科。专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能。

    77 引用 • 37 回帖 • 1 关注
  • MongoDB

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

    91 引用 • 59 回帖
  • Solo

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

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

    1444 引用 • 10083 回帖 • 500 关注
  • OpenCV
    15 引用 • 36 回帖
  • Swift

    Swift 是苹果于 2014 年 WWDC(苹果开发者大会)发布的开发语言,可与 Objective-C 共同运行于 Mac OS 和 iOS 平台,用于搭建基于苹果平台的应用程序。

    34 引用 • 37 回帖 • 555 关注
  • 星云链

    星云链是一个开源公链,业内简单的将其称为区块链上的谷歌。其实它不仅仅是区块链搜索引擎,一个公链的所有功能,它基本都有,比如你可以用它来开发部署你的去中心化的 APP,你可以在上面编写智能合约,发送交易等等。3 分钟快速接入星云链 (NAS) 测试网

    3 引用 • 16 回帖
  • 996
    13 引用 • 200 回帖 • 1 关注
  • 尊园地产

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

    1 引用 • 22 回帖 • 808 关注
  • 面试

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

    326 引用 • 1395 回帖
  • BookxNote

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

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

    1 引用 • 1 回帖 • 3 关注
  • RYMCU

    RYMCU 致力于打造一个即严谨又活泼、专业又不失有趣,为数百万人服务的开源嵌入式知识学习交流平台。

    4 引用 • 6 回帖 • 64 关注
  • SOHO

    为成为自由职业者在家办公而努力吧!

    7 引用 • 55 回帖
  • SEO

    发布对别人有帮助的原创内容是最好的 SEO 方式。

    36 引用 • 200 回帖 • 42 关注
  • Postman

    Postman 是一款简单好用的 HTTP API 调试工具。

    4 引用 • 3 回帖 • 5 关注
  • TensorFlow

    TensorFlow 是一个采用数据流图(data flow graphs),用于数值计算的开源软件库。节点(Nodes)在图中表示数学操作,图中的线(edges)则表示在节点间相互联系的多维数据数组,即张量(tensor)。

    20 引用 • 19 回帖
  • 链书

    链书(Chainbook)是 B3log 开源社区提供的区块链纸质书交易平台,通过 B3T 实现共享激励与价值链。可将你的闲置书籍上架到链书,我们共同构建这个全新的交易平台,让闲置书籍继续发挥它的价值。

    链书社

    链书目前已经下线,也许以后还有计划重制上线。

    14 引用 • 257 回帖 • 6 关注
  • SSL

    SSL(Secure Sockets Layer 安全套接层),及其继任者传输层安全(Transport Layer Security,TLS)是为网络通信提供安全及数据完整性的一种安全协议。TLS 与 SSL 在传输层对网络连接进行加密。

    70 引用 • 193 回帖 • 414 关注
  • 游戏

    沉迷游戏伤身,强撸灰飞烟灭。

    188 引用 • 832 回帖
  • Pipe

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

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

    134 引用 • 1128 回帖 • 110 关注
  • 导航

    各种网址链接、内容导航。

    45 引用 • 177 回帖
  • Webswing

    Webswing 是一个能将任何 Swing 应用通过纯 HTML5 运行在浏览器中的 Web 服务器,详细介绍请看 将 Java Swing 应用变成 Web 应用

    1 引用 • 15 回帖 • 651 关注
  • 又拍云

    又拍云是国内领先的 CDN 服务提供商,国家工信部认证通过的“可信云”,乌云众测平台认证的“安全云”,为移动时代的创业者提供新一代的 CDN 加速服务。

    20 引用 • 37 回帖 • 567 关注
  • 资讯

    资讯是用户因为及时地获得它并利用它而能够在相对短的时间内给自己带来价值的信息,资讯有时效性和地域性。

    56 引用 • 85 回帖 • 3 关注