关于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)
全栈程序员-站长的头像全栈程序员-站长

相关推荐

  • 【吐血整理】Java项目源码分享

    【吐血整理】Java项目源码分享javaservlet+jsp+bean开发开源宅商城系统,未用任何java开源框架实例(七),电商书店,源码下载:jsp+servlet仿当当网电商图书系统实例(八),源码下载:jsp+javabean+servlet开发的mvc简易鞋城在线商城系统各种管理系统:=======实例(一):学生信息管理系统,源码下载:GitHub-yirenyin/J2EE_practice:J2EE学生信息管理系统初级版实例(二):图书馆管理系统,源码下载:1、图书馆管理系统JSP+Ser

    2022年7月8日
  • DataFrame的apply()、applymap()、map()方法[通俗易懂]

    DataFrame的apply()、applymap()、map()方法[通俗易懂]对DataFrame对象中的某些行或列,或者对DataFrame对象中的所有元素进行某种运算或操作,我们无需利用低效笨拙的循环,DataFrame给我们分别提供了相应的直接而简单的方法,apply()和applymap()。其中apply()方法是针对某些行或列进行操作的,而applymap()方法则是针对所有元素进行操作的。1map()方法Themapmethod…

    2022年5月17日
  • NAND FLASH_NAND器件

    NAND FLASH_NAND器件概要:本文介绍了DM368NANDFlash启动的原理,并且以DM368IPNC参考设计软件为例,介绍软件是如何配合硬件实现启动的.芯片上电后是如何启动实现应用功能的?这是许多工程师在看到处理器运行的时候,通常都会问的一个问题.下面我们就以德州仪器的多媒体处理芯片TMS320DM368为例,介绍它的NANDFlash启动原理以及实现.1.NANDFlash启动原理德州…

    2022年8月13日
  • Error:SSL peer shut down incorrectly完美解决。

    Error:SSL peer shut down incorrectly完美解决。

    2021年10月1日
  • allure安装配置「建议收藏」

    allure安装配置「建议收藏」一、下载allurehttps://dl.bintray.com/qameta/generic/io/qameta/allure/allure/2.7.0/allure-2.7.0.zip二、检查本机是否有java的运行环境1、win+r输入cmd回车打开终端窗口打开效果入下2、输入java回车安装成功效果如下:安装未成功效果如下:3、输入javac回车…

    2022年7月26日
  • 太原java技术培训_面试官说java基础不行

    太原java技术培训_面试官说java基础不行二、六大性能调优技术(JVM调优+网络调优+数据库调优+LINUX内核调优+中间件底层探索+容器环境调优)手绘板(脑图)1、JVM调优JVM调优必备理论知识-GcCOLLECTOR-三色标记垃圾回收算法串讲JVM常见参数总结JVM调优实战JVM(HotSpot)核心源码解读JVM核心模块(GC算法)手写实战2、网络调优TCP内核参数JAVAAPI参数IO模型TRADEOFF资源隔离优化网卡、CPU配置调优网络安全的加密算法与数字签名3、数据库调优Mysql性能监

    2022年10月3日

发表回复

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

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