使用Velocity模板技术构建代码生成器

来源:互联网 发布:mastercam编程教程 编辑:程序博客网 时间:2024/05/21 01:47

Velocity 是一个基于 Java 的模板引擎,它允许任何人仅仅简单的使用模板语言来引用由 Java 代码定义的对象,从而实现界面和 Java 代码的分离,使得界面设计人员可以和 Java 程序开发人员同步开发一个遵循 MVC 架构的 web 站点。但是在实际应用过程中,Velocity 又不仅仅被用在了 MVC 的架构中。

在如今特别流行的 MVC 架构模式中,软件各个层次的功能更加独立,同时代码的相似度也更加高。所以我们需要寻找一种来减少软件开发人员重复劳动的方法,让程序员将更多的精力放在业务逻辑以及其他更加具有创造力的工作上。Velocity 这个模板引擎就可以在一定程度上解决这个问题。

Velocity官网地址: http://velocity.apache.org/


一、基本原理

代码生成器的基本原理就是抽取通用的代码编写成模板文件,模板引擎根据模板文件以及输入生成相应代码并持久化到磁盘:

<span style="white-space:pre"></span>/** * @param templateName 模板文件 * @param className    生成的java文件的类名 * @param packageName  包名  * @param map          向velocity context中放置变量的hashmap * @throws Exception */public static void generateCode(String templateName,String className,String packageName,Map<String, String> map) throws Exception{Template template=null;try {template = Velocity.getTemplate(templateName);} catch (Exception e) {e.printStackTrace();}Context context= new VelocityContext();context.put("packageName", packageName);context.put("className", className);for (Map.Entry<String, String> entry : map.entrySet()) {context.put(entry.getKey(), entry.getValue());}File fileDir=new File(basePath+packageName.replace('.', '/'));if(!fileDir.exists()){fileDir.mkdirs();}FileOutputStream outStream = new FileOutputStream(new File(fileDir, className+".java"));OutputStreamWriter writer =  new OutputStreamWriter(outStream,"UTF-8");BufferedWriter sw = new BufferedWriter(writer);template.merge(context,sw);//根据模板文件以及输入的contezt生成代码sw.flush();sw.close();outStream.close();}

一个模板文件的例子:

package ${packageName};import javax.annotation.Resource;import javax.servlet.http.HttpServletRequest;import org.apache.struts2.ServletActionContext;import org.apache.struts2.convention.annotation.Action;import org.apache.struts2.convention.annotation.Namespace;import org.apache.struts2.convention.annotation.Result;import org.apache.struts2.convention.annotation.Results;import org.springframework.stereotype.Controller;import com.opensymphony.xwork2.ActionSupport;import ${serviceImport};/** * ${description} * @author ${author} */@Controller@Namespace("${nameSpace}")@Results( { @Result(name = "list", location = "${resultLocation}.jsp")})public class ${className} extends ActionSupport {@Resourceprivate ${serviceInterface} ${serviceName};/** * 跳转到列表页面 */@Action("${methodName}_list")public String list() {HttpServletRequest  request=ServletActionContext.getRequest();request.setAttribute("entityList", ${serviceName}.getScrollData().getResultlist());return "list";}}
这是个Controller模板文件,基于Struts2的注解技术实现。模板中包名、类名、Controller NameSpace、Service接口、跳转页面、请求路径等都在运行时由velocity模板引擎根据程序的输入动态生成。


二、一个简单的代码生成器例子

根据以上的思想,自己在大学时期开发的一个简单的代码生成器如下所示:

            

         

                                        




最终生成的Action如下所示:

package com.wuwang.agent.action.foo;import javax.annotation.Resource;import javax.servlet.http.HttpServletRequest;import org.apache.struts2.ServletActionContext;import org.apache.struts2.convention.annotation.Action;import org.apache.struts2.convention.annotation.Namespace;import org.apache.struts2.convention.annotation.Result;import org.apache.struts2.convention.annotation.Results;import org.springframework.stereotype.Controller;import com.opensymphony.xwork2.ActionSupport;import com.wuwang.agent.service.foo.FooService;/** *  * @author  * */@Controller@Namespace("/")@Results( { @Result(name = "list", location = "/WEB-INF/page/foo_list.jsp")})public class FooAction extends ActionSupport {@Resourceprivate FooService fooService;/** * 跳转到列表页面 */@Action("foo_list")public String list() {HttpServletRequest  request=ServletActionContext.getRequest();request.setAttribute("entityList", fooService.getScrollData().getResultlist());return "list";}}

封装了通用功能的Domain、Dao、Service、Action源代码都自动生成了。


这个代码生成器比较简单,仅作展示参考。

按照这种思路,其实更复杂的代码生成器也能开发。

0 0
原创粉丝点击