`

Velocity源码浅析(二)

 
阅读更多

原文地址: http://www.khotyn.com/2011/07/22/velocity_sourcecode/

 

很久之前就接触了Velocity,但是一直只会根据它的模板语法写一些模板,非常惭愧,于是最近看了一下Velocity的源代码,在这里记录一下看了以后的一点心得体会。

一、基本概念

对于Velocity是什么东西,我相信这个不用多说,在说Velocity的源代码之前,先看一下几个看Velocity的源代码之前必须需要了解的东西:

JavaCC和JJTree

说到Velocity,不得不谈一下JavaCC,JavaCC是一个用于生成解析器的工具,它可以将一份语法定义(以.jj为后缀的文件)转化成Java代码用于检查一本文本是否符合这一份语法定义。更加具体的信息大家可以查看JavaCC的官网或者看一看这一篇文章。

JJTree是JavaCC提供的一个工具,JJTree可以将一份语法定义(以.jjt为后缀的文件,语法和.jj文件基本相同)转化成Java 代码,这段代码可以检查一份输入是否符合这一份语法定义,并且最后还会生成一颗抽象语法树提供给使用来遍历。更多关于JJTree的内容大家可以看一看这 一篇文章。Velocity就将其模板语法定义成了一个jjt文件,然后根据这一份jjt文件生成了velocity模板的解析器。

抽象语法树(Abstract Syntax Tree)

前面我们已经提到,JJTree工具生成的解析器可以将模板文件解析成一个抽象语法树,这里简单解释一下抽象语法树,抽象语法树是一种表示源代码的 抽象语法结构的方法,这样解释起来可能比较晦涩,我们用例子来看看,假设我们定义了一个加减乘除的语法,其语法和数学上的是一样的,现在有下面一个表达 式:

1 + 2 * 3

最后得到了一棵AST就是这样的:

ast

有了这样一颗AST,整个表达式的求值就可以通过递归的方式来非常快速的进行。

二、模板解析和渲染的过程

Velocity的模板解析过程是由一个输入(可以是一个模板文件,或者是就是一个String或者InputStream)得到一棵抽象语法树的过程。

首先,Velocity为其模板语法定义了一份jjt文件,根据这一份jjt文件,使用JJTree生成了一个解析器。

然后,Velocity将模板解析的过程完全交给了解析器,调用解析器的parse方法直接得到一棵AST,这一棵AST的每一个节点都对应一个 SimpleNode的子类,其中不同的语法元素对应的不同的SimpleNode,比如#if条件表达式对应的SimpleNode是 ASTIfStatement,而#stop指令对应的SimpleNode是ASTStop。

得到了AST以后,模板的渲染就比较简单了,无非就是递归地调用各个节点的SimpleNode的render方法来完成模板的渲染过程,相当简单。

三、方法调用的执行

在了解了模板的渲染过程以后,最想了解的便是模板上的方法调用是怎么在渲染过程中执行的,首先来说明一下对于Velocity里面的引用,比 如$foo这样的,最后都被解析成AST中的ASTReference节点,而对于$foo.name这样的,ASTReference下面有一个 ASTIdentifier节点,$foo.saySomething()这样的,ASTReference下面有一个ASTMethod节点。不论是 ASTMethod还是ASTIdentifier,最后都是通过Uberspect和Introspector这两个类来完成对方法的查找(关于这两个 类的类名,可以见我的另一篇文章 ),最后调用各种Executor来完成对方法的调用。

Uberspect这个类的功能是通过反射(Reflection)和内省(Introspection)来完成对需要调用的方法的获取的,而 Introspector这个类的功能是根据方法名和方法参数在一个类里面寻找Method对象的。另外,为了提高性能,这里面还对Method的数据进 行了缓存(见IntrospectionCacheData,IntrospectorCache和IntrospectorCacheImpl三个 类),以便下次快速可以找到。

找到Method以后,具体的方法的执行由各个Executor执行,每一个Executor都继承了AbstractExecutor,以此来给外部提供统一的接口去调用。

四、整体架构

最后我画了一个Velocity模板解析与渲染部分的整体架构来说明前面的整个过程:

VelocityTemplateParsingRendering

分享到:
评论

相关推荐

    Velocity 源码例子

    ** Velocity 源码分析与应用实例 ** Velocity 是一个基于 Java 的模板引擎,它允许开发者将业务逻辑和页面展示分离,使得Web开发更加高效。Velocity 提供了一种简单但强大的语言来创建动态内容,其核心设计思想是...

    velocity 入门文档及应用源码,很适合做自动代码生成

    4. **velocity(1).rar** 和 **velocity.rar**:这两个RAR文件可能是Velocity的源码或相关示例项目的压缩包,供开发者下载研究。 **总结** Velocity作为一款强大的模板引擎,为Java开发提供了灵活的内容生成解决...

    Struts+Velocity整合示例(含源码)

    通过阅读源码,我们可以学习如何配置Struts2与Velocity的整合,理解Action如何与Velocity模板交互,以及如何在模板中使用Java对象和方法。此外,还可以了解如何调试和优化这种整合,提升Web应用的开发效率和用户体验...

    velocity-1.7-sources.zip

    velocity 的源代码 Velocity 是一个基于 Java 的模板引擎框架,提供的模板语言可以使用在 Java 中定义的对象和变量上。Velocity 是 Apache 基金会的项目,开发的目标是分离 MVC 模式中的持久化层和业务层。但是在...

    velocity项目源代码

    【Velocity项目源代码】是一个基于Java的模板引擎,它被广泛应用于Web开发中,用于生成动态内容。Velocity通过将业务逻辑与表示层分离,提高了Web应用程序的开发效率和可维护性。这个【描述】提到的"Velocity_...

    struts2+Velocity替换jsp项目源码

    通过这个"struts2+Velocity替换jsp项目源码",你可以学习到如何将一个传统的基于JSP的Web应用转换为使用Velocity作为视图层,从而提升项目的可维护性和性能。这是一个很好的实践案例,对于深入理解和掌握Struts2与...

    velocity-tools-2.0-src.zip

    《Velocity Tools 2.0 源码解析与应用探讨》 Velocity Tools 是一个基于 Apache Velocity 的开源工具集,它提供了各种辅助工具,用于简化 Web 开发中的常见任务。在"velocity-tools-2.0-src.zip"这个压缩包中,包含...

    velocity-tools-generic-3.1-API文档-中英对照版.zip

    赠送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-...

    struts2整合velocity含源码

    Struts2和Velocity是两种在Java Web开发中广泛使用的开源框架。Struts2是一个MVC(Model-View-Controller)框架,它极大地简化了Java Web应用程序的开发,而Velocity则是一个快速、简单、可嵌入的Java模板引擎,用于...

    velocity-1.5.jar,velocity-1.6.2-dep.jar,velocity-tools-1.3.jar

    Velocity是Apache软件基金会的一个开源项目,它是一款强大的模板引擎,主要用于生成动态Web内容。 Velocity的主要优点在于其简单易用和高度可扩展性,使得开发者能够将业务逻辑与表现层分离,提高代码的可读性和维护...

    Velocity

    深入研究Velocity的源码有助于理解其工作原理,例如如何解析模板、如何执行指令、如何处理上下文对象等。这不仅可以帮助优化模板设计,还能为自定义扩展提供基础。 ### 学习资源 - 博文链接:...

    Velocity资料

    文档中提到了“源码”和“工具”,这表明Velocity不仅提供了基础的模板引擎功能,而且可能还包含了可供开发者直接使用的源代码以及一些有助于开发和调试的辅助工具。 4. Velocity中文资料: 文件中提到了一些中文...

    velocity为空判断

    #### 方法二:`$null.isNull()` 这是一个更直接的检查方式,无需额外配置。推荐使用此方法,特别是当判断集合对象是否为null时,非常实用。例如: ```velocity #if($null.isNull()) 变量为null #else 变量不为...

    velocity web开发

    “源码”标签意味着 Velocity 是开源的,开发者可以查看和修改其内部实现。对于需要深度定制或优化性能的项目,这非常有用。而“工具”标签则表明 Velocity 是作为开发工具的一部分,帮助开发者构建和维护Web应用。 ...

    velocity的所有jar包

    - **高效性能**:Velocity在编译模板后生成Java源码,然后由JVM执行,这使得其运行速度快且资源消耗低。 - **可扩展性**:Velocity Tools和其他扩展可以增加更多功能,如国际化、表单处理等。 然而,需要注意的是,...

    velocity的jar包

    **Velocity简介** Velocity是Apache软件基金会的一个开源项目,它是一个基于Java的模板引擎,用于生成动态网站内容。Velocity被设计成一个轻量级的、快速的、非侵入式的模板语言,使得开发者能够将HTML页面的展示...

    velocity插件

    【 Velocity 插件详解】 Velocity 是一款基于 Java 的模板引擎,它被广泛应用于 Web 开发中,特别是作为 Apache Struts 和 Spring MVC 框架的一部分。Velocity 插件则是为了在开发环境中提供对 Velocity 模板语言的...

    velocity和freemarker的比较

    对于标签“源码”和“工具”,我们可以进一步研究这两个模板引擎的源代码,理解其工作原理,并掌握如何在项目中有效利用它们。提供的文件列表似乎包含了一些日志文件、项目配置文件和源代码库,这可能是项目开发或...

    Velocity 和 FreeMarker区别

    #### 二、使用便捷性 **FreeMarker**相比**Velocity**而言,在大多数情况下更加容易使用。主要原因是FreeMarker内置了更多的功能,例如自动转义机制、丰富的内置函数等,这使得开发者无需额外编写工具类或方法即可...

    spring+mybatis+velocity项目demo

    分享一个spring+mybatis+velocity项目demo,该项目是之前给一个学第学习用的,主要基于springMVC、mybatis、velocity搭建的,使用maven构建,其中zai service层编写了两个简单组件,一个是email发送,一个是认证授权...

Global site tag (gtag.js) - Google Analytics