目录
在MVC开发模式下,View离不开模板引擎,在Java语言中模板引擎使用得最多是JSP、Velocity和FreeMarker,在MVC编程开发模式中,必不可少的一个部分是V的部分。V负责前端的页面展示,也就是负责生产最终的HTML,V部分通常会对应一个编码引擎,当前众多的MVC框架都已经可以将V部分独立开来,可以与众多的模板引擎集成。
Velocity总体架构
从代码结构上看,Velocity主要分为app、context、runtime和一些辅助util几个部分。
APP模块
其中app主要封装了一些接口,暴露给使用者使用。主要有两个类,分别是Velocity(单例)和VelocityEngine。
前者主要封装了一些静态接口,可以直接调用,帮助你渲染模板,只要传给Velocity一个模板和模板中对应的变量值就可以直接渲染。
VelocityEngine类主要是供一些框架开发者调用的,它提供了更加复杂的接口供调用者选择,MVC框架中初始化一个VelocityEngine:
以上是Spring MVC创建Velocity模板引擎的VelocityEngine实例的代码段,先创建一个VelocityEngine实例,再将配置参数设置到VelocityEngine的Property中,最终调用init方法初始化。
Context模块
Context模块主要封装了模板渲染需要的变量,它的主要作用有两点:
- 便于与其他框架集成,起到一个适配器的作用,如MVC框架内部保存的变量往往在一个Map中,这样MVC框架就需要将这个Map适配到Velocity的context中。
- Velocity内部做数据隔离,数据进入Velocity的内部的不同模块需要对数据做不同的处理,封装不同的数据接口有利于模块之间的解耦。
Context类是外部框架需要向Velocity传输数据必须实现的接口,具体实现时可以集成抽象类AbstractContext,例如,Spring MVC中直接继承了VelocityContext,调用构造函数创建Velocity需要的数据结构。
另外一个接口InternetEventContext主要是为扩展Velocity事件处理准备的数据接口,当你扩展了事件处理、需要操作数据时可以实现这个接口,并且处理你需要的数据。
Runtime模块
整个Velocity的核心模块在runtime package下,这里会将加载的模板解析成JavaCC语法树,Velocity调用mergeTemplate方法时会渲染整棵树,并输出最终的渲染结果。
RuntimeInstance类
RuntimeInstance类为整个Velocity渲染提供了一个单例模式,它也是Velocity的一个门面,封装了渲染模板需要的所有接口,拿到了这个实例就可以完成渲染过程了。它与VelocityEngine不同,VelocityEngine代表了整个Velocity引擎,它不仅包括模板渲染,还包括参数设置及数据的封装规则,RuntimeInstance仅仅代表一个模板的渲染状态。
JJTree渲染过程解析
下面是一段Velocity的模板代码vm和这段代码解析成的语法树:
Velo