关于java代码生成器

关于java代码生成器讲代码生成器之前先要说说模板,什么叫模板呢,举个例子吧,汇款单都见过吧,你不填写的那些内容都属于模板范畴说到这应该明白了吧,模板就是把共性提取出来反复使用,节约时间、工作量。。。。。那跟代码生成器有什么关系呢,思考一下在编程语言中所有的语言是不是都用共性或者说规范,这些都是固定不变的,在具体点,软件行业也是分主营业务的,比如OA、CRM、ERP、SCM等等,那么各个业务方向的软件

大家好,又见面了,我是你们的朋友全栈君。

讲代码生成器之前先要说说模板,什么叫模板呢,举个例子吧,汇款单都见过吧,你不填写的那些内容都属于模板范畴

说到这应该明白了吧,模板就是把共性提取出来反复使用,节约时间、工作量。。。。。

那跟代码生成器有什么关系呢,思考一下在编程语言中所有的语言是不是都用共性或者说规范,这些都是固定不变的,在具体点,软件行业也是分主营业务 的,比如OA、CRM、ERP、SCM等等,那么各个业务方向的软件是不是也有其行业特点,这是不是也是固定的,那么这就完了,这些独特的地方是不是可以 提取出来作为模板呢,不言而喻

言归正传,说到模板就不得不说现在主流的模板技术了,FreeMarker、Velocity(这个google在用),模板技术推崇一种模式:

输出=模板+数据,所以运用到代码生成器上也是一样的道理,举个简单例子比如要生成一个javabean组件,就普通的pojo类,

那么先分析一下生成这种类有什么共性呢,关键字就不用说了,getter和setter方法都是get+属性名uppercase首字母和set+ 属性名uppercase首字母,还有“{}”、“;”、“()”等等这些都是不变的,那么这些内容就可以作为模板内容,包名、类名、属性名这些是人为要 取的,这些是变化的,故变的这部分就作为数据,这样就可以根据不同的‘数据’来生成不同的javabean

 

项目准备:先去down个freemarker.jar包,  http://freemarker.org/freemarkerdownload.html

上篇讨论了代码生成器的原理,输出=模板+数据,那么现在就生成一个Student.java文件做个简单例子。

首先先写出模板,先解决一个问题,上篇有讲到属性名首字母大写的问题

由于freemarker中不支持将首字母大写(属性名中用到),那么自己先写一个自定义宏如下:

  1. package  com;  
  2.   
  3. import  java.io.IOException;  
  4. import  java.io.Writer;  
  5. import  java.util.Map;  
  6.   
  7. import  freemarker.core.Environment;  
  8. import  freemarker.template.TemplateDirectiveBody;  
  9. import  freemarker.template.TemplateDirectiveModel;  
  10. import  freemarker.template.TemplateException;  
  11. import  freemarker.template.TemplateModel;  
  12. import  freemarker.template.TemplateModelException;  
  13.   
  14. public   class  UpperFirstCharacter  implements  TemplateDirectiveModel {  
  15.   
  16.     public   void  execute(Environment env,  
  17.             Map params, TemplateModel[] loopVars,  
  18.             TemplateDirectiveBody body)  
  19.             throws  TemplateException, IOException {  
  20.         // Check if no parameters were given:   
  21.         if  (!params.isEmpty()) {  
  22.             throw   new  TemplateModelException(  
  23.                     “This directive doesn’t allow parameters.” );  
  24.         }  
  25.         if  (loopVars.length !=  0 ) {  
  26.                 throw   new  TemplateModelException(  
  27.                     “This directive doesn’t allow loop variables.” );  
  28.         }  
  29.           
  30.         // If there is non-empty nested content:   
  31.         if  (body !=  null ) {  
  32.             // Executes the nested body. Same as <#nested> in FTL, except   
  33.             // that we use our own writer instead of the current output writer.   
  34.             body.render(new  UpperCaseFilterWriter(env.getOut()));  
  35.         } else  {  
  36.             throw   new  RuntimeException( “missing body” );  
  37.         }  
  38.     }  
  39.       
  40.     /**  
  41.      * A {@link Writer} that transforms the character stream to upper case  
  42.      * and forwards it to another {@link Writer}.  
  43.      */    
  44.     private   static   class  UpperCaseFilterWriter  extends  Writer {  
  45.          
  46.         private   final  Writer out;  
  47.              
  48.         UpperCaseFilterWriter (Writer out) {  
  49.             this .out = out;  
  50.         }  
  51.   
  52.         public   void  write( char [] cbuf,  int  off,  int  len)  
  53.                 throws  IOException {  
  54. //            char[] transformedCbuf = new char[len];   
  55. //            for (int i = 0; i < len; i++) {
       
  56. //                transformedCbuf[i] = Character.toUpperCase(cbuf[i + off]);   
  57. //            }   
  58. //            out.write(transformedCbuf);   
  59.             cbuf[0 ] = Character.toUpperCase(cbuf[ 0 ]);  
  60.             out.write(String.valueOf(cbuf).trim());///把右边空格去掉   
  61.         }  
  62.   
  63.         public   void  flush()  throws  IOException {  
  64.             out.flush();  
  65.         }  
  66.   
  67.         public   void  close()  throws  IOException {  
  68.             out.close();  
  69.         }  
  70.     }  
  71.   
  72. }  
[Java] 
view plain
copy

  1. package com;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.Writer;  
  5. import java.util.Map;  
  6.   
  7. import freemarker.core.Environment;  
  8. import freemarker.template.TemplateDirectiveBody;  
  9. import freemarker.template.TemplateDirectiveModel;  
  10. import freemarker.template.TemplateException;  
  11. import freemarker.template.TemplateModel;  
  12. import freemarker.template.TemplateModelException;  
  13.   
  14. public class UpperFirstCharacter implements TemplateDirectiveModel {  
  15.   
  16.     public void execute(Environment env,  
  17.             Map params, TemplateModel[] loopVars,  
  18.             TemplateDirectiveBody body)  
  19.             throws TemplateException, IOException {  
  20.         // Check if no parameters were given:  
  21.         if (!params.isEmpty()) {  
  22.             throw new TemplateModelException(  
  23.                     “This directive doesn’t allow parameters.”);  
  24.         }  
  25.         if (loopVars.length != 0) {  
  26.                 throw new TemplateModelException(  
  27.                     “This directive doesn’t allow loop variables.”);  
  28.         }  
  29.           
  30.         // If there is non-empty nested content:  
  31.         if (body != null) {  
  32.             // Executes the nested body. Same as <#nested> in FTL, except  
  33.             // that we use our own writer instead of the current output writer.  
  34.             body.render(new UpperCaseFilterWriter(env.getOut()));  
  35.         } else {  
  36.             throw new RuntimeException(“missing body”);  
  37.         }  
  38.     }  
  39.       
  40.     /** 
  41.      * A {@link Writer} that transforms the character stream to upper case 
  42.      * and forwards it to another {@link Writer}. 
  43.      */   
  44.     private static class UpperCaseFilterWriter extends Writer {  
  45.          
  46.         private final Writer out;  
  47.              
  48.         UpperCaseFilterWriter (Writer out) {  
  49.             this.out = out;  
  50.         }  
  51.   
  52.         public void write(char[] cbuf, int off, int len)  
  53.                 throws IOException {  
  54. //            char[] transformedCbuf = new char[len];  
  55. //            for (int i = 0; i < len; i++) {
      
  56. //                transformedCbuf[i] = Character.toUpperCase(cbuf[i + off]);  
  57. //            }  
  58. //            out.write(transformedCbuf);  
  59.             cbuf[0] = Character.toUpperCase(cbuf[0]);  
  60.             out.write(String.valueOf(cbuf).trim());///把右边空格去掉  
  61.         }  
  62.   
  63.         public void flush() throws IOException {  
  64.             out.flush();  
  65.         }  
  66.   
  67.         public void close() throws IOException {  
  68.             out.close();  
  69.         }  
  70.     }  
  71.   
  72. }  

 

下面呢就可以编写模板了,代码如下:

  1. package  ${
     package };  
  2.   
  3. //这个地方可以事先定义好需要的类   
  4. import  java.util.Date;  
  5.   
  6. import  java.io.Serializable;  
  7.   
  8. public   class  ${className}  implements  Serializable{  
  9. <#list properties as pro>  
  10.     private  ${pro.proType} ${pro.proName};  
  11. </#list>  
  12.       
  13. <#list properties as pro>  
  14.     public   void  set< @upperFC >${pro.proName}</ @upperFC >(${pro.proType} ${pro.proName}){  
  15.         this .${pro.proName}=${pro.proName};  
  16.     }  
  17.       
  18.     public  ${pro.proType} get< @upperFC >${pro.proName}</ @upperFC >(){  
  19.         return   this .${pro.proName};  
  20.     }  
  21.       
  22. </#list>  
  23. }  
[Java] 
view plain
copy

  1. package ${
    package};  
  2.   
  3. //这个地方可以事先定义好需要的类  
  4. import java.util.Date;  
  5.   
  6. import java.io.Serializable;  
  7.   
  8. public class ${className} implements Serializable{  
  9. <#list properties as pro>  
  10.     private ${pro.proType} ${pro.proName};  
  11. </#list>  
  12.       
  13. <#list properties as pro>  
  14.     public void set<@upperFC>${pro.proName}</@upperFC>(${pro.proType} ${pro.proName}){  
  15.         this.${pro.proName}=${pro.proName};  
  16.     }  
  17.       
  18.     public ${pro.proType} get<@upperFC>${pro.proName}</@upperFC>(){  
  19.         return this.${pro.proName};  
  20.     }  
  21.       
  22. </#list>  
  23. }  

模板文件取名为javabean.html,在com包下

下面编写测试类:

  1. package  com;  
  2.   
  3. import  java.io.File;  
  4. import  java.io.FileOutputStream;  
  5. import  java.io.IOException;  
  6. import  java.io.OutputStreamWriter;  
  7. import  java.util.ArrayList;  
  8. import  java.util.HashMap;  
  9. import  java.util.List;  
  10. import  java.util.Map;  
  11.   
  12. import  freemarker.template.Configuration;  
  13. import  freemarker.template.Template;  
  14. import  freemarker.template.TemplateException;  
  15.   
  16. public   class  Test {  
  17.   
  18.     /**  
  19.      * @param args  
  20.      */   
  21.     public   static   void  main(String[] args) {  
  22.         //System.out.println(System.getProperty(“user.dir”)+”============”);   
  23.         Configuration cfg = new  Configuration();  
  24.         try  {  
  25.             cfg.setClassForTemplateLoading(Test.class  “/com” ); //指定模板所在的classpath目录   
  26.             cfg.setSharedVariable(“upperFC”  new  UpperFirstCharacter()); //添加一个”宏”共享变量用来将属性名首字母大写   
  27.             Template t = cfg.getTemplate(“javabean.html” ); //指定模板   
  28.             FileOutputStream fos = new  FileOutputStream( new  File( “d:/Student.java”)); //java文件的生成目录   
  29.               
  30.             //模拟数据源   
  31.             Map data = new  HashMap();  
  32.             data.put(“package”  “edu” ); //包名   
  33.             data.put(“className”  “Student” );  
  34.               
  35.             List pros = new  ArrayList();  
  36.             Map pro_1 = new  HashMap();  
  37.             pro_1.put(“proType” , String. class .getSimpleName());  
  38.             pro_1.put(“proName”  “name” );  
  39.             pros.add(pro_1);  
  40.               
  41.             Map pro_2 = new  HashMap();  
  42.             pro_2.put(“proType” , String. class .getSimpleName());  
  43.             pro_2.put(“proName”  “sex” );  
  44.             pros.add(pro_2);  
  45.               
  46.             Map pro_3 = new  HashMap();  
  47.             pro_3.put(“proType” , Integer. class .getSimpleName());  
  48.             pro_3.put(“proName”  “age” );  
  49.             pros.add(pro_3);  
  50.               
  51.             data.put(“properties” , pros);  
  52.             t.process(data, new  OutputStreamWriter(fos, “utf-8” )); //   
  53.             fos.flush();  
  54.             fos.close();  
  55.         } catch  (IOException e) {  
  56.             e.printStackTrace();  
  57.         } catch  (TemplateException e) {  
  58.             e.printStackTrace();  
  59.         }  
  60.     }  
  61.   
  62. }  
[Java] 
view plain
copy

  1. package com;  
  2.   
  3. import java.io.File;  
  4. import java.io.FileOutputStream;  
  5. import java.io.IOException;  
  6. import java.io.OutputStreamWriter;  
  7. import java.util.ArrayList;  
  8. import java.util.HashMap;  
  9. import java.util.List;  
  10. import java.util.Map;  
  11.   
  12. import freemarker.template.Configuration;  
  13. import freemarker.template.Template;  
  14. import freemarker.template.TemplateException;  
  15.   
  16. public class Test {  
  17.   
  18.     /** 
  19.      * @param args 
  20.      */  
  21.     public static void main(String[] args) {  
  22.         //System.out.println(System.getProperty(“user.dir”)+”============”);  
  23.         Configuration cfg = new Configuration();  
  24.         try {  
  25.             cfg.setClassForTemplateLoading(Test.class“/com”);//指定模板所在的classpath目录  
  26.             cfg.setSharedVariable(“upperFC”new UpperFirstCharacter());//添加一个”宏”共享变量用来将属性名首字母大写  
  27.             Template t = cfg.getTemplate(“javabean.html”);//指定模板  
  28.             FileOutputStream fos = new FileOutputStream(new File(“d:/Student.java”));//java文件的生成目录  
  29.               
  30.             //模拟数据源  
  31.             Map data = new HashMap();  
  32.             data.put(“package”“edu”);//包名  
  33.             data.put(“className”“Student”);  
  34.               
  35.             List pros = new ArrayList();  
  36.             Map pro_1 = new HashMap();  
  37.             pro_1.put(“proType”, String.class.getSimpleName());  
  38.             pro_1.put(“proName”“name”);  
  39.             pros.add(pro_1);  
  40.               
  41.             Map pro_2 = new HashMap();  
  42.             pro_2.put(“proType”, String.class.getSimpleName());  
  43.             pro_2.put(“proName”“sex”);  
  44.             pros.add(pro_2);  
  45.               
  46.             Map pro_3 = new HashMap();  
  47.             pro_3.put(“proType”, Integer.class.getSimpleName());  
  48.             pro_3.put(“proName”“age”);  
  49.             pros.add(pro_3);  
  50.               
  51.             data.put(“properties”, pros);  
  52.             t.process(data, new OutputStreamWriter(fos,“utf-8”));//  
  53.             fos.flush();  
  54.             fos.close();  
  55.         } catch (IOException e) {  
  56.             e.printStackTrace();  
  57.         } catch (TemplateException e) {  
  58.             e.printStackTrace();  
  59.         }  
  60.     }  
  61.   
  62. }  

 

运行一下测试类,在D盘可以找到一个Student.java的文件,打开看看对不对

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/133050.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Unity Cutout材质 实现网格效果[通俗易懂]

    Unity Cutout材质 实现网格效果[通俗易懂]Cutout????效果????贴图准备????材质制作????效果????如图所示铁丝网不是模型只是一张128*128的贴图制作的材质,这样可以极大的降低模型面数制作也很速度!????贴图准备????ps中制作一张128*128尺寸带透明通道的图,如下所示:????材质制作????设置RenderingMode为Cutout模式,并且把贴图放到Albedo槽中????可以调节Tiling属性增加或减少网格密度…

    2022年9月23日
    0
  • 数据结构与算法学习笔记

    本文是王争老师的《算法与数据结构之美》的学习笔记,详细内容请看王争的专栏。有不懂的地方指出来,我做修改。数据结构与算法思维导图数据结构指的是“一组数据的存储结构”,算法指的是“操作数据的一组方法”。数据结构是为算法服务的,算法是要作用再特定的数据结构上的。最常用的数据结构预算法:数据结构:数组、链表、栈、队列、散列表、二叉树‘、堆、跳表、图、Tire树 算法:递归…

    2022年4月7日
    210
  • 分布式计算概述_分布式计算与处理

    分布式计算概述_分布式计算与处理**分布式计算是当前计算机领域常见的名词,那么到底什么是分布式,什么又是分布式计算呢?今天和大家共同研究一下这个话题。**分布式计算的概念一个分布式系统是由若干通过网络互联的计算机组成的软硬件系统,且这些计算机互相配合以完成一个共同目标(往往这个共同目标称为“项目”)分布式计算的优缺点优点:1.超大规模2.虚拟化3.高可靠性4.通用性5.高伸缩性6.按需服务7….

    2022年10月24日
    0
  • RabbitVCS安装

    RabbitVCS安装给大家推荐使用RabbitVCS,类似与TortoiseSVN。下面具体安装RabbitVCS的方法步骤如下:第一步:sudoadd-apt-repositoryppa:rabbitvcs/ppa第二步:根据第一步的情况来是否跳过该步骤,如果第一步出现导入key,那第二步可以跳过,否则需要导入keysudoapt-keyadv–keyserverkeyserver.u

    2022年7月18日
    28
  • bfs官网_山谷和山脉

    bfs官网_山谷和山脉FGD小朋友特别喜欢爬山,在爬山的时候他就在研究山峰和山谷。为了能够对旅程有一个安排,他想知道山峰和山谷的数量。给定一个地图,为FGD想要旅行的区域,地图被分为 n×n 的网格,每个格子 (i,j) 的高度 w(i,j) 是给定的。若两个格子有公共顶点,那么它们就是相邻的格子,如与 (i,j) 相邻的格子有(i−1,j−1),(i−1,j),(i−1,j+1),(i,j−1),(i,j+1),(i+1,j−1),(i+1,j),(i+1,j+1)。我们定义一个格子的集合 S 为山峰(山谷)当且仅当:

    2022年8月9日
    4
  • golang 最新激活码(JetBrains全家桶)

    (golang 最新激活码)这是一篇idea技术相关文章,由全栈君为大家提供,主要知识点是关于2021JetBrains全家桶永久激活码的内容IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.html0BXA05X8YC-eyJsa…

    2022年3月30日
    281

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号