关于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的文件,打开看看对不对

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • java.math.BigDecimal保留两位小数[通俗易懂]

    java.math.BigDecimal保留两位小数[通俗易懂]java保留两位小数问题:一:四舍五入(四舍五入形式保留两位小数,注意模式ROUND_HALF_UP)doublef=2345.2345;BigDecimalb=newBigDecimal(f);doublef1=b.setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();保…

  • 拉姆达表达式启动一个线程

    拉姆达表达式启动一个线程publicstaticvoidmain(String[]args){Mythreadmythread=newMythread();newThread(()-&gt;mythread.r()).start();}staticclassMythread{publicvoidr(){intcount=0;for(inti=0;i&lt;=100;i++){S…

  • vue与jquery的区别_vue 3

    vue与jquery的区别_vue 31.jquery介绍:想必大家都用过jquery吧,这个曾经也是现在依然最流行的web前端js库,可是现在无论是国内还是国外他的使用率正在渐渐被其他的js库所代替,随着浏览器厂商对HTML5规范统一遵循以及ECMA6在浏览器端的实现,jquery的使用率将会越来越低2.vue介绍:vue是一个兴起的前端js库,是一个精简的MVVM。从技术角度讲,Vue.js专注于MVVM模型的ViewM…

    2022年10月16日
  • 纳兰诗词

    纳兰诗词“空负凌云万丈志,一生襟抱未曾开”,情雅成诗,爱淡成词,如果没有潋滟坦白的心思,是无法走进古人留在书册中的幻境的。凡心所向,皆是虚妄。——一个人吃饭,旅行,到处走走停停;也一个人看书,弹琴,自己对话谈心。自我收敛,内心沉静,是我希望获得的心境,对纳兰容若不熟的人,恐怕会比较熟悉另外一个名字,纳兰明珠。如果我再说一句《七剑下天山》,恐十白你已经在点头微笑了:你说的是这个人。纳兰容若诞于清顺治

  • 未来将是越界的时代

    未来将是越界的时代

  • nginx做正向代理_正向代理和反向代理图

    nginx做正向代理_正向代理和反向代理图环境在一个网络环境中,只有一台服务器可以使用互联网,而其他内网服务器都可以访问到这台互联网服务器,于是,我们可以通过nginx的正向代理访问互联网地址此处举例:互联网服务器IP:192.168.1.100内网服务器IP:192.168.1.101部署安装包:nginx-1.20.2.tar.gzproxy_connect模块:gitclonehttps://github.com/chobits/ngx_http_proxy_connect_module.git操…

    2022年10月21日

发表回复

您的电子邮箱地址不会被公开。

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