`
雪国列车
  • 浏览: 76453 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Velocity初始化过程解析

 
阅读更多

Velocity是一个表示层的模板框架,作为 jsp 的替代者,有着很多优势。小巧方便,不必使用 el 或者其他表示层技术来展示页面,感觉是一个很新颖的技术。

Velocity作为 MVC 框架中的 V 存在,和普通 jsp 页面有着不同,它是一种 template 引擎,利用先编辑完的格式来作为大纲,把一些需要变化的地方作为参数传入,显示时将模板和参数合并,达到最终输出的样子。本文使用目前最新的 velocity1.6.2.jar 包进行解析。

 

最根本的velocity 就是由 template engine context 组成。

1、首先创建一个 template (如果是用在 web 上就是一个 html 文件),将需要参数化或实例化的地方用跟 context 有关的符号标记出来 , 标记时使用 velocity template language 。而 template 应该可以是任意的文本。

2、给 context 设定一些值,这些值用来替换在 template 中被标记的地方。

3、利用 engine template 中需要替换的地方用 context 中的值替换掉,也就是所谓的 merge ,从而得到该模板的实例。

 

简单的用java 代码来输出就是:

 

VelocityEngine velocity =  new  VelocityEngine();

VelocityContext context =  new  VelocityContext();

context.put( "name" "czy" );

Template template = velocity.getTemplate( "/src/main/resources/test.vm" );

BufferedWriter   writer =  new  BufferedWriter( new  OutputStreamWriter(System. out ));

template.merge(context, writer);

writer.flush();

writer .close();

 

至于我们为什么使用 VelocityEngine  而不是使用Velocity 类,或者说两者有什么区别,请看 VelocityEngine  Velocity 类解析

 

    我们假设使用普通的velocityEngine 来作为引擎,来进入初始化的过程。

Velocity的初始化有多种方式:

1 init()

2 init(Properties p)

3 init(String propertiesName)

 

第一种init() 方式是最简单的方式,当我们的程序没有配置类似 velocity.properties 这样的文件的时候,就会使用默认的配置文件来初始化,默认的配置文件的位置在

org/apache/velocity/runtime/defaults/velocity.properties

而将Velocity 应用在 WEB 的时候,默认的配置文件使用的是

org/apache/velocity/tools/view/servlet/velocity.properties

 

在初始化前,velocity 会把配置文件的属性和值读取后保存在内存中,初始化时, velocity 将会初始化以下几个方面:

 

1 Logging   System  日志系统

2 ResourceManager  资源加载器

3 EventHandler  事件句柄

4 Parser   Pool  解析池

5 Global   Cache  全局缓存

6 Static   Content   Include   System

7 Velocimacro   System  宏

 

1、 Logging System

顾名思义,是进行日志的初始化工作,Veloicty 会使用 LogManager 来默认创建一个 LogChute 的实例。 Velocity 早些时候是使用 LogSystem 来作为日志的接口,而现在则使用 LogChute 。第一个最初最初的默认实例叫做 HoldingLogChute ,其实里面就是一个 Vector 来保存信息,用来作为初始化日志系统的日志实例,呵呵,很拗口。

在创建了第一个系统内置的日志实例后,才会开始真正的创建日志系统,velocity 会根据配置文件里的信息,查找一个名叫 runtime.log.logsystem 的属性,一旦配置文件中有配置这个属性,则会开始去创建日志系统。当velocity 没有配置 runtime.log.logsystem 这个属性的时候,则会继续寻找 runtime.log.logsyste m.class 这个属性,默认的velocity.properties 配置文件中,这个属性的值按顺序依次为

1、AvalonLogChute 

2、Log4JLogChute

3、CommonsLogLogChute

4、ServletLogChute

5、JdkLogChute

当然,velocity 不会使用那么多个日志系统,只会使用第一个能实例化的日志系统。

如果之前的创建工作都失败的话,那么意味着用户没有设置值或者是没有找到类,velocity 将会使用系统统默认的 SystemLogChute 来输出日志,这个日志系统使用 System.err 方式输出日志。

一旦使用 runtime.log.logsystem 或者 runtime.log.logsyste m.class属性创建日志系统成功后, velocity 就会把 HoldingLogChute 替换成新的日志系统。这样,日志的初始化才真正的结束。

 

2、 ResourceManager

资源加载器是velocity 加载资源使用的一个工具。

Velocity的配置文件里有个属性叫 Resource.manager.class 默认的class

org.apache.velocity.runtime.resource.ResourceManagerImpl

Velocity会尝试初始化 ResourceManagerImpl ,其中会查找 resource.loader 这个属性, resource.loader 这个属性是可以有多个的,每个Loader 都会生效。

ResourceLoader一共有 7 种:

 

1 ClasspathResourceLoader

2、DataSourceResourceLoader

3、FileResourceLoader

4、JarResourceLoader

5、StringResourceLoader

6、URLResourceLoader

7、WebappLoader

 

默认的是第3 FileResourceLoader 。除了第 7 webappLoader velocity-tools 包作为 velocity 的附属工具后来添加的,其余 6 个都 velocity 包自带的, 已经足够满足大多数的需求,当然,如果觉得这些都不适用,你也可以自己实现一个。实现一个资源加载器,实际上很简单,只要继承ResourceLoader ,实现它的几个方法就可以了。

所谓的资源加载器指的就是velocity 读取文件的方法,有直接从文件读取的,有从 jar 包中读取的,也有从类路径中读取的,基本上只要自己重写 getResourceStream 方法就可以。

在初始化的过程中,会读取 resource.manager.logwhenfound resource.manager.cache.class 这两个属性,同时,也会进行资源缓存的初始化操作。

 

3 EventHandler

Velocity在渲染页面的时候,提供了不同的 EventHanlder ,供开发者 callback 。说白了就是Velocity 渲染页面的不同工具,用户可以自定义响应的事件。 Velocity提供了对模板解析过程事件的处理,用户可以响应模板产生的事件。 

 

org.apache.velocity.app.event.EventHandler,是一个最简单的接口。我们可以通过实现这个接口来处理页面上不同的信息。


 

以下是这个接口的一些扩展接口。

1) IncludeEventHandler

在使用#include(),#parse() 语法的时候,允许开发修改 include 或者 parse 文件的路径(一般用于资源找不到的情况)

IncludeEventHandler有两个实现类,分别是 IncludeNotFound IncludeRelativePath

 


当找不到#include 指令的文件时 ,IncludeNotFound 类会去做一些处理,例如去增加一个 eventhandler.include.notfound = notfound.vm 的配置,当然,如果不存在notfound.vm ,也会给出 " Can't find include not found page "的提示。

2) InvalidReferenceEventHandler

当渲染页面的时候,一旦遇到非法的reference ,就会触发此事件。开发者可以侦听此事件,用于错误的报告,或者修改返回的内容。

ReportInvalidReferences 是它的一个实现类, 用于报告无效的refenrences 。如果在 velocity 的配置文件中使用了 eventhandler.invalidreference.exception = true 配置,在运行过程中碰到第一个无效的refenrences 就会抛出 ParseErrorRuntimeException 异常,执行暂停。如果配置为false 的话,则会将错误先收在 InvalidReferenceInfo 列表对象中,运行照旧。

3) MethodExceptionEventHandler

渲染模板,一旦发现调用的方法抛出异常的时候,就会触发此事件。允许开发者处理这个异常,输出友好信息或者抛出异常。必须返回一个值用于模板的渲染。 

4) NullSetEventHandler

当使用#set() 语法,设置一个 null 值的时候,会触发此事件。目前 Velocity 官方没有提供默认实现

5) ReferenceInsertionEventHandler

当渲染变量(reference )的时候,就会触发此事件。允许开发者返回更加友好的值--一般用于内容的 escape ,比如 HtmlEscape 等。

 

4、 Parser Pool

Velocity会使用类似线程池的机制来解析页面。配置的 key parser.pool.class parser.pool.size

默认的实现类为 o rg.apache.velocity.util.SimplePoolVelocity

velocity 启动 需要创建模板解析器的个数 默认 20 对一般用户来说足够了 即使这个值小了, Velocity 也会运行时根据系统需要动态增加 ( 但增加的不会装入 解析 池中).  新增时会在日志中输出信息

 

5 Directives

所谓的指令指的就是在页面上能用一些类似标签的东西。 V elocity默认的指令文件位置在 org/apache/velocity/runtime/defaults/directive.properties

在这个文件中定义了一些默认的指令,例如:

directive.1 = org.apache.velocity.runtime.directive.Foreach

directive.2 = org.apache.velocity.runtime.directive.Include

directive.3 = org.apache.velocity.runtime.directive.Parse

directive.4 = org.apache.velocity.runtime.directive.Macro

directive.5 = org.apache.velocity.runtime.directive.Literal

directive.6 = org.apache.velocity.runtime.directive.Evaluate

directive.7 = org.apache.velocity.runtime.directive.Break

directive.8 = org.apache.velocity.runtime.directive.Define

我们在vm 文件中可以直接使用 foreach 等指令来让我们的页面更加的灵活。

 

5、 Velocimacro(宏配置)

Velocity engine 运行时, 会载入一个全局的宏文件。 所有模板都可访问 文件 (Velocimacros ). 这个文件位置在相对于资源文件的根目录下 velocity 默认的配置项为 velocimacro.library = VM_global_library.vm

此外,还有一些其他配置来处理宏的不同使用情况,例如:

velocimacro.permissions.allow.inline = tru e 定义在模板中是否可用#macro() 指令定义一个新的宏 默认为true ,表示所有的vm 都可以新建宏,但是要 注意可能会把全局的宏配置给替换掉。

velocimacro.permissions.allow.inline.to.replace.global = false 控制用户定义的宏是否可以可以替换Velocity 全局宏。

velocimacro.library.autoreload = false 控制宏是否自动载入 。当值 true 将根据是否修改而决定是否需要 重新加载,这个特性 可在调试时很方便,不需重启你的服务器

 

 

此之外,还有些组件:

Anakia:一个示例应用,该应用允许不使用 xsl 处理 xml

Application servers:对所有主流的 servers servlet 提供了支持,比如有一个 VelocityServlet 类。

  • 大小: 36.4 KB
  • 大小: 26.3 KB
分享到:
评论

相关推荐

    详解velocity模板使javaWeb的html+js实现模块化

    详解velocity模板使javaWeb的html+js实现模块化 页面上一些基础数据或者其他页面经常用到部分,可以独立出来做成小组件,组件预留调用入口,需要的页面直接调用即可。 如图,页面中的展示分类和搜索.../** 初始化一级

    基于springMVC的论坛

    解压后,先初始化mysql,运行mysql。运行resin目录下的httpd.exe文件即可(请确保resin解压在D盘根目录下面,由于配置的时候是写死的引用D:\resin-pro-3.1.12\lib\aspectjweaver-1.7.0.jar)共有3个解压缩文件,由于...

    基于spring MVC的论坛002

    解压后,先初始化mysql,运行mysql。运行resin目录下的httpd.exe文件即可(请确保resin解压在D盘根目录下面,由于配置的时候是写死的引用D:\resin-pro-3.1.12\lib\aspectjweaver-1.7.0.jar)共有3个解压缩文件,由于...

    基于spring MVC的论坛

    解压后,先初始化mysql,运行mysql。运行resin目录下的httpd.exe文件即可(请确保resin解压在D盘根目录下面,由于配置的时候是写死的引用D:\resin-pro-3.1.12\lib\aspectjweaver-1.7.0.jar)共有3个解压缩文件,由于...

    Spring API

    13.6. 本地化解析器 13.6.1. AcceptHeaderLocaleResolver 13.6.2. CookieLocaleResolver 13.6.3. SessionLocaleResolver 13.6.4. LocaleChangeInterceptor 13.7. 使用主题 13.7.1. 简介 13.7.2. 如何定义主题...

    Spring中文帮助文档

    13.6. 本地化解析器 13.6.1. AcceptHeaderLocaleResolver 13.6.2. CookieLocaleResolver 13.6.3. SessionLocaleResolver 13.6.4. LocaleChangeInterceptor 13.7. 使用主题 13.7.1. 简介 13.7.2. 如何定义主题...

    springboot学习思维笔记.xmind

    Bean的初始化和销毁 Java配置方式 注解方式 Profile @Profile 通过设定jvm的spring.profiles.active参数 web项目设置在Servlet的context parameter中 事件Application Event 自定义事件,...

    Spring-Reference_zh_CN(Spring中文参考手册)

    13.6. 本地化解析器 13.6.1. AcceptHeaderLocaleResolver 13.6.2. CookieLocaleResolver 13.6.3. SessionLocaleResolver 13.6.4. LocaleChangeInterceptor 13.7. 使用主题 13.7.1. 简介 13.7.2. 如何定义主题 13.7.3...

    spring chm文档

    3.3.5. 延迟初始化bean 3.3.6. 自动装配(autowire)协作者 3.3.7. 依赖检查 3.3.8. 方法注入 3.4. bean的作用域 3.4.1. Singleton作用域 3.4.2. Prototype作用域 3.4.3. 其他作用域 3.4.4. 自定义作用域 ...

    Spring in Action(第2版)中文版

    2.5.3初始化和销毁bean 2.6小结 第3章高级bean装配 3.1声明父bean和子bean 3.1.1抽象基bean类型 3.1.2抽象共同属性 3.2方法注入 3.2.1基本的方法替换 3.2.2获取器注入 3.3注入非springbean 3.4注册自定义...

    Spring in Action(第二版 中文高清版).part2

    2.5.3 初始化和销毁Bean 2.6 小结 第3章 高级Bean装配 3.1 声明父Bean和子Bean 3.1.1 抽象基Bean类型 3.1.2 抽象共同属性 3.2 方法注入 3.2.1 基本的方法替换 3.2.2 获取器注入 3.3 注入非Spring Bean ...

    Spring in Action(第二版 中文高清版).part1

    2.5.3 初始化和销毁Bean 2.6 小结 第3章 高级Bean装配 3.1 声明父Bean和子Bean 3.1.1 抽象基Bean类型 3.1.2 抽象共同属性 3.2 方法注入 3.2.1 基本的方法替换 3.2.2 获取器注入 3.3 注入非Spring Bean ...

    Spring 2.0 开发参考手册

    13.6. 本地化解析器 13.6.1. AcceptHeaderLocaleResolver 13.6.2. CookieLocaleResolver 13.6.3. SessionLocaleResolver 13.6.4. LocaleChangeInterceptor 13.7. 使用主题 13.7.1. 简介 13.7.2. 如何定义主题...

    Spring面试题

    在 XML 文件中定义的 Bean 是被消极加载的,这意味在需要 bean 之前,bean 本身不会被初始化。要从 BeanFactory 检索 bean,只需调用 getBean() 方法,传入将要检索的 bean 的名称即可,如清单 2 所示。 清单 2. ...

    Maven权威指南 很精典的学习教程,比ANT更好用

    Maven权威指南 Authors Tim O'Brien (Sonatype, Inc.) , John Casey (Sonatype, Inc.) , Brian Fox (Sonatype, Inc.) , Bruce Snyder () , Jason Van Zyl (Sonatype, Inc.) , Juven Xu () Abstract ...

Global site tag (gtag.js) - Google Analytics