zoukankan      html  css  js  c++  java
  • Velocity初始化过程解析

    velocity就是由templateenginecontext组成。

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

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

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

     

    Velocity的初始化有多种方式:

     

    1init()

     

    2init(Properties p)

     

    3init(String propertiesName) 

     

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

    默认的配置文件的位置在org/apache/velocity/runtime/defaults/velocity.properties

     

    应用在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. Velocimacro System 宏

    Logging System

     

     

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

     

    1. AvalonLogChute
    2. Log4JLogChute
    3. CommonsLogLogChute
    4. ServletLogChute
    5. JdkLogChute

     

    当然,velocity不会使用那么多个日志系统,只会使用第一个能实例化的日志系统。如果之前的创建工作都失败的话,那么意味着用户没有设置值或者是没有找到类,velocity将会使用系统统默认的SystemLogChute来输出日志,这个日志系统使用System.err方式输出日志。一旦使用runtime.log.logsystem或者runtime.log.logsystem.class属性创建日志系统成功后,velocity就会把HoldingLogChute替换成新的日志系统。这样,日志的初始化才真正的结束。

     

    ResourceManager 

     

    资源加载器是velocity加载资源使用的一个工具。Velocity的配置文件里有个属性叫Resource.manager.class,默认的classorg.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 

    默认的是第3FileResourceLoader。除了第7webappLoadervelocity-tools包作为velocity的附属工具后来添加的,其余6个都velocity包自带的,如果觉得这些都不适用,你也可以自己实现一个。实现一个资源加载器只要继承ResourceLoader,实现它的几个方法就可以了。所谓的资源加载器指的就是velocity读取文件的方法,有直接从文件读取的,有从jar包中读取的,也有从类路径中读取的,基本上只要自己重写getResourceStream方法就可以。在初始化的过程中,会读取resource.manager.logwhenfoundresource.manager.cache.class这两个属性,同时,也会进行资源缓存的初始化操作。

    EventHandler 

     

     

    用户可以自定义响应的事件,Velocity提供了对模板解析过程事件的处理,用户可以响应模板产生的事件。 

     

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

     

    1)IncludeEventHandler

     

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

     

    IncludeEventHandler有两个实现类,分别是IncludeNotFoundIncludeRelativePath

     

    当找不到#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会使用类似线程池的机制解析页面。配置的keyparser.pool.classparser.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宏将根据是否修改而决定是否需要重新加载,这个特性可在调试时很方便,不需重启你的服务器。 

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    回首2016,展望2017
    认识多线程
    对CloseHandle用法的理解
    CDC、HDC、pDC之间的关系
    兼容位图和兼容DC的理解
    窗口中显示bmp图片的过程
    创建一个bmp格式的简单方法
    说明为什么Button控件不能使用CustomDraw技术
    MFC自绘Button按钮分析和实现
    VC之美化界面篇
  • 原文地址:https://www.cnblogs.com/wade-luffy/p/5997871.html
Copyright © 2011-2022 走看看