Velocity初始化过程解析
velocity就是由template,engine,context组成。
1、首先创建一个template(如果是用在web上就是一个html文件),将需要参数化或实例化的地方用跟context有关的符号标记出来,标记时用velocity template language。而template应该可以是任意的文本。
2、给context设定一些值,这些值用来替换在template中被标记的地方。
3、利用engine将template中需要替换的地方用context中的值替换掉,也就是所谓的merge,从而得到该模板的实例。
Velocity的初始化有多种方式:
1、init()
2、init(Properties p)
3、init(String propertiesName)
第一种init()方式是最简单的方式,当我们的程序没有配置类似velocity.properties这样的文件的时候,就会使用默认的配置文件来初始化,
默认的配置文件的位置在org/apache/velocity/runtime/defaults/velocity.properties
应用在WEB的时候,默认的配置文件使用的是org/apache/velocity/tools/view/servlet/velocity.properties
在初始化前,velocity会把配置文件的属性和值读取后保存在内存中,初始化时,velocity将会初始化以下几个方面:
- Logging System 日志系统
- ResourceManager 资源加载器
- EventHandler 事件句柄
- Parser Pool 解析池
- Global Cache 全局缓存
- Velocimacro System 宏
Logging System
velocity会根据配置文件里的信息,查找一个名叫runtime.log.logsystem的属性,一旦配置文件中有配置这个属性,则会开始去创建日志系统。当velocity没有配置runtime.log.logsystem这个属性的时候,则会继续寻找runtime.log.logsystem.class这个属性,默认的velocity.properties配置文件中,这个属性的值按顺序依次为
- AvalonLogChute
- Log4JLogChute
- CommonsLogLogChute
- ServletLogChute
- JdkLogChute
当然,velocity不会使用那么多个日志系统,只会使用第一个能实例化的日志系统。如果之前的创建工作都失败的话,那么意味着用户没有设置值或者是没有找到类,velocity将会使用系统统默认的SystemLogChute来输出日志,这个日志系统使用System.err方式输出日志。一旦使用runtime.log.logsystem或者runtime.log.logsystem.class属性创建日志系统成功后,velocity就会把HoldingLogChute替换成新的日志系统。这样,日志的初始化才真正的结束。
ResourceManager
资源加载器是velocity加载资源使用的一个工具。Velocity的配置文件里有个属性叫Resource.manager.class,默认的class是org.apache.velocity.runtime.resource.ResourceManagerImpl。Velocity会尝试初始化ResourceManagerImpl,其中会查找resource.loader这个属性,resource.loader这个属性是可以有多个的,每个Loader都会生效。
ResourceLoader一共有7种:
- ClasspathResourceLoader
- DataSourceResourceLoader
- FileResourceLoader
- JarResourceLoader
- StringResourceLoader
- URLResourceLoader
- WebappLoader
默认的是第3个FileResourceLoader。除了第7个webappLoader是velocity-tools包作为velocity的附属工具后来添加的,其余6个都velocity包自带的,如果觉得这些都不适用,你也可以自己实现一个。实现一个资源加载器只要继承ResourceLoader,实现它的几个方法就可以了。所谓的资源加载器指的就是velocity读取文件的方法,有直接从文件读取的,有从jar包中读取的,也有从类路径中读取的,基本上只要自己重写getResourceStream方法就可以。在初始化的过程中,会读取resource.manager.logwhenfound和resource.manager.cache.class这两个属性,同时,也会进行资源缓存的初始化操作。
EventHandler
用户可以自定义响应的事件,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等。
Parser Pool
Velocity会使用类似线程池的机制来解析页面。配置的key为parser.pool.class和parser.pool.size。默认的实现类为org.apache.velocity.util.SimplePoolVelocity。
velocity启动时需要创建模板解析器的个数. 默认为20个,对一般用户来说足够了. 即使这个值小了,Velocity也会运行时根据系统需要动态增加(但增加的不会装入解析池中). 新增时会在日志中输出信息。
Global Cache 全局缓存
开启全局缓存配置项 file.resource.loader.cache=true file.resource.loader.modificationCheckInterval=-1
Template t = getTemplate(stack, velocityManager.getVelocityEngine(), invocation, finalLocation, encoding); VelocityResult.java :
protected Template getTemplate(ValueStack stack, VelocityEngine velocity, ActionInvocation invocation, String location, String encoding) throws Exception {
if (!location.startsWith("/")) {
location = invocation.getProxy().getNamespace() + "/" + location;
} Template template = velocity.getTemplate(location, encoding); return template;
} VelocityEngine.java
public Template getTemplate(String name, String encoding)
throws ResourceNotFoundException, ParseErrorException, Exception
{
return ri.getTemplate( name, encoding );
} RuntimeInstance.java
public Template getTemplate(String name, String encoding)
throws ResourceNotFoundException, ParseErrorException, Exception
{
requireInitialization(); return (Template)
resourceManager.getResource(name,
ResourceManager.RESOURCE_TEMPLATE, encoding);
} ResourceManagerImpl.java
public Resource getResource(final String resourceName, final int resourceType, final String encoding)
throws ResourceNotFoundException,
ParseErrorException,
Exception
{
String resourceKey = resourceType + resourceName;
Resource resource = globalCache.get(resourceKey); ResourceCacheImpl.java
public Resource get( Object key )
{
return (Resource) cache.get( key );
}
Velocimacro(宏配置)
当Velocity engine运行时,会载入一个全局的宏文件。所有模板都可访问该宏文件(Velocimacros). 这个文件位置在相对于资源文件的根目录下。velocity默认的配置项为velocimacro.library=VM_global_library.vm。此外,还有一些其他配置来处理宏的不同使用情况,例如:
velocimacro.permissions.allow.inline=true定义在模板中是否可用#macro()指令定义一个新的宏。默认为true,表示所有的vm都可以新建宏,但是要注意可能会把全局的宏配置给替换掉。
velocimacro.permissions.allow.inline.to.replace.global=false控制用户定义的宏是否可以可以替换Velocity的全局宏。
velocimacro.library.autoreload=false控制宏是否自动载入。当值为true时宏将根据是否修改而决定是否需要重新加载,这个特性可在调试时很方便,不需重启你的服务器。
Velocity初始化过程解析的更多相关文章
- 解析Java类和对象的初始化过程
类的初始化和对象初始化是 JVM 管理的类型生命周期中非常重要的两个环节,Google 了一遍网络,有关类装载机制的文章倒是不少,然而类初始化和对象初始化的文章并不多,特别是从字节码和 JVM 层次来 ...
- [转载]解析 Java 类和对象的初始化过程
原文地址:http://www.ibm.com/developerworks/cn/java/j-lo-clobj-init/index.html 由一个单态模式引出的问题谈起 类的初始化和对象初始化 ...
- Velocity工作原理解析和优化
在MVC开发模式下,View离不开模板引擎,在Java语言中模板引擎使用得最多是JSP.Velocity和FreeMarker,在MVC编程开发模式中,必不可少的一个部分是V的部分.V负责前端的页面展 ...
- 【初探Spring】------Spring IOC(三):初始化过程---Resource定位
我们知道Spring的IoC起到了一个容器的作用,其中装得都是各种各样的Bean.同时在我们刚刚开始学习Spring的时候都是通过xml文件来定义Bean,Spring会某种方式加载这些xml文件,然 ...
- 【初探Spring】------Spring IOC(二):初始化过程---简介
首先我们先来看看如下一段代码 ClassPathResource resource = new ClassPathResource("bean.xml"); DefaultList ...
- Spring IoC容器的初始化过程
Spring IoC容器的初始化包括 BeanDefinition的Resource定位.载入和注册 这三个基本的过程.IoC容器的初始化过程不包含Bean依赖注入的实现.Bean依赖的注入一般会发生 ...
- Spring IoC容器初始化过程学习
IoC容器是什么?IoC文英全称Inversion of Control,即控制反转,我么可以这么理解IoC容器: 把某些业务对象的的控制权交给一个平台或者框架来同一管理,这个同一管理的平台可以称为I ...
- IoC容器的初始化过程
1.简单来说,IoC容器的初始化是由前面介绍的refresh()方法来启动的,这个方法标志着IoC容器的正式启动. 2.具体来说,这个启动包括BeanDefinition的Resource定位.载入和 ...
- Spring之IOC容器初始化过程
Ioc容器的初始化是由refresh()方法来启动的,这个方法标志着Ioc容器的正式启动. 具体来说这个启动过程包括三个基本过程: 1.BeanDifinition的Resource定位 2.Bean ...
随机推荐
- nginx 用户登录认证
1.配置nginx server { listen ; server_name kibana.×××.com; location / { auth_basic "secret"; ...
- MSP430G2553 Launchpad 硬件I2C驱动
一.USCI I2C 驱动介绍 对于MSP430G2553,硬件I2C由外设USCI(Universal Serial Communication Interface)提供.USCI又分为USCI_A ...
- wp8.1 SQLite的基本使用
SQLite是一个轻量级的关系型数据库,正是由于其精悍小巧,在移动端平台被广泛应用,但不适合处理大量数据和批量操作.它的底层是由C语言编写,最初设计是为了应用于嵌入式,占用资源非常低且简单易用,而且绝 ...
- Rest-assured 写日志到 log4j
背景: 采用Rest-assured,日志采用log4j,发现Rest-assured本身只支持打印日志到控制台,但期望打印到文件中以便排查问题 请求打印的语句只能输出到控制台 given().log ...
- Cookie客户端缓存.Session.Application
Cookie客户端缓存. 1.引言 随着浏览器的处理能力不断增强,越来越多的网站开始考虑将数据存储在「客户端」,那么久不得不谈本地存储了. 本地存储的好处: 一是避免取回数据前页面一片空白,如果不需要 ...
- docker 存储驱动之 overlay2
overlay2 简介 OverlayFS是一种和AUFS很类似的文件系统,与AUFS相比,OverlayFS有以下特性: 1) 更简单地设计 2) 从3.18开始,就进入了Linux内核主线 3) ...
- 解决 UnicodeEncodeError: 'ascii' codec can't encode characters in position 问题
在开头加上 import sys reload(sys) sys.setdefaultencoding( "utf-8" ) Python自然调用ascii编码解码程序去处理字符流 ...
- 0基础浅谈反射型xss (1)
0X1:在学习xss之前,先快速学习相关的HTML代码 1. <input>标签 文本域用法: <input type="text" /> Type的作 ...
- 如何在Cordova Android 7.0.0 以下版本集成最新插件 极光插件为例
前提 Cordova Android 7.0.0开始改变了项目安卓平台的架构.新建一个空项目分别添加Android 6.4.0 和 Android 7.0.0平台: cordova platform ...
- leetcode 198 打家劫舍 Python 动态规划
打家劫舍 你是一个专业的小偷,计划偷窃沿街的房屋.每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警. 给定 ...