一、概述
Velocity模板引擎处理机制分为五个基本步骤:
- 引擎初始化,通过设置的引擎属性初始化引擎,包括国际化支持,ResourceLoader设置,字符编码等。
- 获取并解析模板文件,首先通过资源加载器(ResourceLoader)将模板文件加载到内存(转化为InputStream),然后通过AST(Abstract Syntax Tree)解析器将InputStream解析为一个AST。
- 创建一个Context
- 将模板渲染所需的参数放入context
- 执行模板渲染,产生输出流。渲染过程中通过遍历该模板对应的AST,调用相应节点的处理器执行渲染。
整个处理流程如下图所示:
二、详细渲染流程
下面以一个简单的模板template.vm为例,详细解释渲染过程。
VelocityMergeTest.java
public class VelocityMergeTest {
public static void main(String[] args) {
VelocityEngine ve = new VelocityEngine();
ve.setProperty(Velocity.RESOURCE_LOADER, "class");
ve.setProperty("class.resource.loader.class",
"org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
try {
//引擎初始化
ve.init();
//加载解析模板
Template tp = ve.getTemplate("template.vm");
//创建context
Context context = new VelocityContext();
//设置Context中参数值
context.put("foo", "VV");
StringWriter writer = new StringWriter();
//执行渲染
tp.merge(context, writer);
System.out.println(writer.toString());
} catch (Exception e) {
}
}
}
template.vm
<html>
<body>
Hello $foo world!
</body>
</html>
1.引擎初始化
ve.setProperty("class.resource.loader.class",
"org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
设置引擎的资源加载使用ClasspathResourceLoader。
ve.init()执行引擎的初始化。
2.加载解析模板
当执行ve.getTemplate("template.vm")时,首先通过ResourceLoader将tempalte加载为InputStream,然后通过Parser生成如下Token集合:
{[<html> <body> Hello], [$foo], [world! </body> </html> ]},
可以发现velocity根本不关系模板最终要渲染出来的是html还是什么的其他的东西,也就以为这所有的html标签对velocity来讲都是纯文本。
最终构建的AST如下
根节点下有三个子节点:
- [<html> <body> Hello]对应的ASTText节点;
- [$foo]对应的ASTReference节点;
- [world! </body> </html> ]对应的ASTText节点
Velocity引擎在这里有个优化策略,可以针对生成的语法树进行cache。
3.创建context并设置参数
Context context = new VelocityContext();
context.put("foo", "VV");
创建一个context,并在其中放入一个foo=VV的参数。
4.执行渲染
当执行tp.merge(context, writer);时,模板遍历其对应的AST树,执行每个节点的渲染过程。如ASTText节点只是简单的将文本写入writer。ASTReference节点需要从context中获取引用的参数foo的值VV,将$foo替换,并写入到writer中。Velocity的AST中有多种节点,如ASTIdentitor等,有些需要反射机制处理。当整个AST遍历结束,也就意味着模板渲染结束,渲染的结果位于writer流中。
三、关于AST解析
Velocity作为模板语言,其核心在与模板文件的解析,构建AST。Velocity的解析器是通过JavaCC构建的,JavaCC(Java Complier Complier)是一个用于生成解析器的工具,可以根据语法定义(.jj文件)生成用于校验一份文本是否符合该语法定义的java代码。JJTree是JavaCC中提供的一种根据语法定义(.jjt文件)生成构建符合该语法定义的文本的语法树的java代码的工具。
Velocity源码包中提供了用于构建velocity语法解析的的jjt文件,位于src/parser/Parser.jjt。可以自己手动从源码构建Velocity的解析器。步骤如下:
1.下载安装JavaCC,到http://javacc.java.net/下载即可,velocity的解析器需要3.2版本以上。下载后解压即可。
2.使用JJTree生成节点定义:
$ javacc-5.0/bin/jjtree Parser.jjt
这一过程中会生成节点定义的Java文件和Parser.jj语法定义文件
3.使用JavaCC生成解析器
$ javacc-5.0/bin/javacc Parser.jj
最终会生成Parser.java解析器和个节点定义。
参考资料
《Velocity Developer Guide》http://velocity.apache.org/engine/devel/developer-guide.html
《JavaCC》http://javacc.java.net/
《Velocity源码分析》http://www.khotyn.com/2011/07/22/velocity_sourcecode/
《Velocity的一些优化记录》http://agapple.iteye.com/blog/1051724
相关推荐
Velocity 源码例子
NULL 博文链接:https://twb.iteye.com/blog/265761
Velocity 是一个基于 Java 的模板引擎框架,提供的模板语言可以使用在 Java 中定义的对象和变量上。Velocity 是 Apache 基金会的项目,开发的目标是分离 MVC 模式中的持久化层和业务层。但是在实际应用过程中,...
入门文档及应用源码,很适合做自动代码生成 包括:Velocity的中文指南\ velocity中文手册\ \基于Ant+Velocity的简单代码生成器的思路与实现
本课程从velocity engine也就是velocity引擎开始, 先讲解velocity的基本使用以及基础语法 , 然后再讲解velocity 的进阶内容velocity Tools , 以及velocity作为web项目的视图改如何使用 , 每一部分都会有一个综合案例...
赠送jar包:velocity-tools-generic-3.1.jar; 赠送原API文档:velocity-tools-generic-3.1-javadoc.jar; 赠送源代码:velocity-tools-generic-3.1-sources.jar; 赠送Maven依赖信息文件:velocity-tools-generic-...
Velocity模板引擎Velocity模板引擎Velocity模板引擎Velocity模板引擎Velocity模板引擎Velocity模板引擎Velocity模板引擎Velocity模板引擎Velocity模板引擎Velocity模板引擎
Velocity是一个基于java的模板引擎(template engine)。它允许任何人仅仅简单的使用模板语言(template language)来引用由java代码定义的对象。 当Velocity应用于web开发时,界面设计人员可以和java程序开发人员...
Velocity_Hibernat项目源代码。
分享一个spring+mybatis+velocity项目demo,该项目是之前给一个学第学习用的,主要基于springMVC、mybatis、velocity搭建的,使用maven构建,其中zai service层编写了两个简单组件,一个是email发送,一个是认证授权...
Velocity是一个基于java的模板引擎(template engine)。它允许任何人仅仅简单的使用模板语言(template language)来引用由java代码定义的对象。 当Velocity应用于web开发时,界面设计人员可以和java程序开发人员...
Velocity 是一个基于Java的模版引擎。它允许web 页面设计者引用JAVA代码预定义的方法。Web 设计者可以根据MVC模式和JAVA程序员并行工作,这意味着Web设计者可以单独专注于设计良好的站点,而程序员则可单独专注于...
Velocity是一个基于java的模板引擎(template engine)。它允许任何人仅仅简单的使用模板语言(template language)来引用由java代码定义的对象。 当Velocity应用于web开发时,界面设计人员可以和java程序开发人员...
Velocity Velocity Velocity Velocity Velocity Velocity Velocity Velocity Velocity Velocity
Velocity 和 FreeMarker区别 对于大部分的应用来说,使用 FreeMarker 比 Velocity 更简单,因为 Velocity 还必须编写一些自定义的
赠送jar包:velocity-engine-core-2.3.jar; 赠送原API文档:velocity-engine-core-2.3-javadoc.jar; 赠送源代码:velocity-engine-core-2.3-sources.jar; 赠送Maven依赖信息文件:velocity-engine-core-2.3.pom;...
Velocity是一个基于java的模板引擎(template engine)。它允许任何人仅仅简单的使用模板语言(template language)来引用由java代码定义的对象。 当Velocity应用于web开发时,界面设计人员可以和java程序...
注:在velocity中使用$2.5这样的货币标识是没有问题得的,因为velocity中的变量总是以一个大写或者小写的字母开始的。 (2) 变量规范的写法 ${name} ,也可以写成:$name。提倡用前面的写法。 例如:你希望通过一个...
Velocity是一个基于Java的模版引擎。它允许web 页面设计者引用JAVA代码预定义的方法。Web 设计者可以根据MVC模式和JAVA程序员并行工作,这意味着Web设计者可以单独专注于设计良好的站点,而程序员则可单独专注于编写...
赠送jar包:velocity-engine-core-2.3.jar 赠送原API文档:velocity-engine-core-2.3-javadoc.jar 赠送源代码:velocity-engine-core-2.3-sources.jar 包含翻译后的API文档:velocity-engine-core-2.3-javadoc-...