`
successfulroof
  • 浏览: 74338 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Velocity 分析

 
阅读更多

 

 

       Velocity是什么?这里就不做分析了!重点写一写velocity的工作机制,如果文章中哪里有问题还请各位指出,以防误人子弟

其实简单的说,velocity分两大块:

一、资源加载

         使用velocity,我们可以通过一次编写模板而达到多次复用的效果,运用起来也十分的方便,相应速度也比较理想,因为velocity本身也提供模板的缓存功能,对比每次读取文件来说也是要快很多!而且模板缓存原理也是根据文件的修改时间来判断的,如果缓存lastModified < modifiedTime缓存失效,重新加载文件载入缓存!

        1.资源加载器初始化

//主要工作类:VelocityEngine
获取模板方法:
/**
*@param templateName 模板名称
*@param encoding 加载文件编码,默认:ISO-8859-1
**/
velocityEngine.getTemplate(templateName,encoding);

        主要加载VM文件类:ResourceManagerImpl ,manager初始化方法分析

    

 public synchronized void initialize(final RuntimeServices rsvc)
        throws Exception
    {
        if (isInit) //是否初始化,防止重入
        {
            log.debug("Re-initialization of ResourceLoader attempted and ignored.");
            return;
        }
	//资源加载器
        ResourceLoader resourceLoader = null;
       
        // runtimeService 主要用来存储加载文件的一些参数的KEY。如:加载路    径
        this.rsvc = rsvc;
        log = rsvc.getLog();

        log.trace("Default ResourceManager initializing. (" + this.getClass() + ")");
       //组装资源加载器,主要就从runtimeservice中拿出配置的加载器,
       //如果没有配置资源加载器,默认是使用 
     // org.apache.velocity.runtime.resource.loader.FileResourceLoader
       //现在是junit单元测试,使用的是:ClasspathResourceLoader
      /**加载器支持放入List,你同时可以使用多个资源加载器,
         *在一个资源加载器加载不到资源的时候,会使用下一个加载器去加载 
        * 资源加载器都会放入sourceInitializerList
        **/
        assembleResourceLoaderInitializers();
       
        for (Iterator it = sourceInitializerList.iterator(); it.hasNext();)
        {
            /**
             *
             * in as an instance.扩展属性,如:具体文件加载目录,加载器。个人
             *绝对velocity的参数设置比较繁琐,又支持多个类里面设置,容易搞混
             */
            ExtendedProperties configuration = (ExtendedProperties) it.next();
          //从配置冲获取 资源加载器
            String loaderClass = StringUtils.nullTrim(configuration.getString("class"));
            ResourceLoader loaderInstance = (ResourceLoader) configuration.get("instance");

            if (loaderInstance != null)
            {
                resourceLoader = loaderInstance;
            }
            else if (loaderClass != null)
            {
                resourceLoader = ResourceLoaderFactory.getLoader(rsvc, loaderClass);
            }
            else
            {
                String msg = "Unable to find '" +
                          configuration.getString(RESOURCE_LOADER_IDENTIFIER) +
                          ".resource.loader.class' specification in configuration." +
                          " This is a critical value.  Please adjust configuration.";
                log.error(msg);
                throw new Exception(msg);
            }

            resourceLoader.commonInit(rsvc, configuration);
            resourceLoader.init(configuration);
            resourceLoaders.add(resourceLoader);
        }

        /*
         * now see if this is overridden by configuration
         */

        logWhenFound = rsvc.getBoolean(RuntimeConstants.RESOURCE_MANAGER_LOGWHENFOUND, true);

        /*
         *  获取 资源缓存器默认ResourceCacheImpl
         */

        String cacheClassName = rsvc.getString(RuntimeConstants.RESOURCE_MANAGER_CACHE_CLASS);

        Object cacheObject = null;

        if (org.apache.commons.lang.StringUtils.isNotEmpty(cacheClassName))
        {

            try
            {
                cacheObject = ClassUtils.getNewInstance(cacheClassName);
            }
            catch (ClassNotFoundException cnfe)
            {
                String msg = "The specified class for ResourceCache (" + cacheClassName +
                          ") does not exist or is not accessible to the current classloader.";
                log.error(msg, cnfe);
                throw cnfe;
            }

            if (!(cacheObject instanceof ResourceCache))
            {
                String msg = "The specified resource cache class (" + cacheClassName +
                          ") must implement " + ResourceCache.class.getName();
                log.error(msg);
                throw new RuntimeException(msg);
            }
        }

        /*
         *  if we didn't get through that, just use the default.
         */
        if (cacheObject == null)
        {
            cacheObject = new ResourceCacheImpl();
        }

        globalCache = (ResourceCache) cacheObject;
        //初始化资源缓存器的参数,包括缓存文件个数,使用LRUMap缓存
        globalCache.initialize(rsvc);

        log.trace("Default ResourceManager initialization complete.");
    } //上面是资源加载器的初始化

        2.资源加载器加载文件

       

 String resourceKey = resourceType + resourceName;
     //缓存中取资源
        Resource resource = globalCache.get(resourceKey);

        if (resource != null)
        {
            try
            {  //防止重入
                if (resource.requiresChecking())
                {
                   //刷新资源文件,判断修改时间是否有变化
                    resource = refreshResource(resource, encoding);
                }
            }
            catch (ResourceNotFoundException rnfe)
            {
               //文件找不到重新加载,清理缓存
                globalCache.remove(resourceKey);

                return getResource(resourceName, resourceType, encoding);
            }
            catch (ParseErrorException pee)
            {//...
            }
            catch (RuntimeException re)
            {//...
            }
        }
        else
        {
            try
            {
                //去磁盘加载vm文件
                resource = loadResource(resourceName, resourceType, encoding);
             //缓存功能是否开启 
            //REOURCE_LOADER_NAME.resource.loader.cache 通过这个key
            //来设置,REOURCE_LOADER_NAME 是设置resource loader 时候的key
          //engine.setProperty(Velocity.RESOURCE_LOADER,REOURCE_LOADER_NAME 
                if (resource.getResourceLoader().isCachingOn())
                {
                    globalCache.put(resourceKey, resource);
                }
            }
            catch (ResourceNotFoundException rnfe)
            { //...            }
        }

        return resource;

   //先保存一下

 

/** 整理一下初始化资源加载器的参数**/
参数可以直接velocityEngine.setProperties(key,value);
也可以extendedProperties = new ExtendedProperties();然后放入这个扩展属性中,然后把扩展属性设置到引擎属性velocityEngine.setExtendedProperties
如果两个都设置,底层会做两个properties的合并,当然也没必要两个一起弄了,让出出问题。
下面都是properties中需要添加的属性的key和value
1. resource.loader = reourceLoader (资源加载器名称,名字随便取)
2. reourceLoader.resource.loader.class =ClasspathResourceLoader.class.getName(); //junit 资源加载器
3. reourceLoader.cache=true (是否缓存资源文件)
4. reourceLoader.modificationCheckInterval=0 (检查文件修改时间,默认为0,每次都检查)

 

         

二、文件渲染

 首先值得注意的是SimplePool 性能值得考究,RuntimeConstants.PARSER_POOL_SIZE大小值得思考。RuntimeConstants.PARSER_POOL_CLASS 可以替换原有的池,底层inputStream转换为char[]

 有关渲染过程找到了两篇比较好的文章:

http://jiangbo.me/blog/2011/08/19/velocity_overview/

http://www.khotyn.com/2011/07/22/velocity_sourcecode/

 

 上传了一篇淘宝关于velocity优化的文章

 

分享到:
评论

相关推荐

    Seurat-to-RNA-Velocity:将Seurat对象与RNA Velocity结合使用的指南

    本指南将演示如何结合RNA Velocity分析使用已处理/标准化的Seurat对象。 请记住,尽管Seurat是基于R的,但是所有可用的RNA Velocity软件/软件包都是Python,因此我们将在两者之间来回移动。 我们将使用以下程序: ...

    JAVAEE Velocity例子工程

    示例代码分析** `VelocityTest` 文件可能是项目中的主要源代码文件,它可能包含了初始化Velocity上下文、加载模板和渲染输出的过程。例如,它可能有以下代码片段: ```java VelocityContext context = new ...

    Velocity

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

    velocity 电子书

    - 使用Velocity Profiler工具进行性能分析和调试。 8. **最佳实践** - 学习如何编写可维护、可扩展的模板,避免模板过载,保持良好的代码组织。 9. **实际应用案例** - 书中可能会涵盖Velocity在邮件模板、报告...

    maven velocity

    通过分析这些文件,我们可以深入学习如何在实际项目中应用Maven和Velocity的整合。 总之,Maven和Velocity的整合提供了强大的项目管理和模板处理能力,使得Java Web应用的开发变得更加高效和灵活。通过理解和实践,...

    apache velocity介绍及资料

    10. **案例分析**:手册可能包含实际项目中的例子,帮助读者理解如何在不同场景下使用Velocity。 通过阅读这份中文手册,你可以深入了解Velocity的工作原理,掌握其使用技巧,从而在实际开发中更好地利用Velocity来...

    Mastering.Apache.Velocity

    ### 实践案例分析 #### 八、Velocity 在实际项目中的应用 - **示例一:新闻系统**:在新闻系统中,使用 Velocity 渲染文章列表和详情页。 - **示例二:报表生成**:在企业应用中,使用 Velocity 生成各种报表,如...

    JavaScript模板引擎Velocity.js.zip

    Velocity.js 是velocity... 语法分析和模板渲染分离 基本完全支持velocity语法 浏览器使用支持模板之间相互引用,依据kissy模块加载机制 三个Helper,友好的数据模拟解决方案 Vim Syntax 标签:Velocity

    Velocity之HelloWorld配置

    **源码分析** 在深入学习Velocity时,查看源码是很有帮助的。`VelocityEngine`类是 Velocity 的核心,它负责初始化配置、加载模板以及执行模板合并。`VelocityContext`则用于存储模板中使用的变量。当你查看这些类的...

    简单的velocity工程

    同时,分析`Vt`文件,可以掌握Velocity的配置与使用方法,这对于提升Java Web开发能力是非常有帮助的。 在实际应用中,Velocity常与Spring MVC、Struts等框架结合使用,构建MVC架构的Web应用。它可以帮助开发者专注...

    让人蛋疼的velocity减法运算

    由于没有具体的错误描述或代码示例,以上分析是基于VTL常见问题的一般性解答。在实际解决问题时,通常需要查看详细的日志、错误消息,或者阅读相关源代码来定位问题所在。如果在项目中遇到类似问题,建议查阅...

    velocity文档

    #### 二、Velocity的应用实例:MudStore案例分析 假设你是一家名为“MudStore”的在线商店的网页设计师,该店主要出售泥浆产品。为了提升用户体验,决定采用Velocity来实现个性化的页面展示。 - **客户个性化需求*...

    velocity实现静态页面分页

    四、实例分析 "PageList"可能是用于存储分页数据的一个类或者文件名,它可能包含了分页所需的信息,如当前页、总页数、每页数据等。在实际项目中,你可以创建一个PageList.java类,包含这些属性和方法,然后在...

    当前流行的模板引擎效率分析(velocity,freeMarker,Smarty4j,httl)

    本篇文章将对四个流行的Java模板引擎——Velocity、FreeMarker、Smarty4j以及HTTL进行效率分析,旨在探讨它们在处理业务逻辑编译和性能方面的优劣。 1. Velocity: Velocity是Apache软件基金会的一个开源项目,以其...

    关于velocity的基础知识

    #### 四、示例场景分析 假设我们正在为一家名为“在线MUD商店”的企业开发一个电子商务网站。该网站需要展示各种类型的Mud产品,并且能够根据用户的购买历史推荐相应的产品。在这种情况下,Velocity可以帮助我们更...

    Spring+SpringMVC+Mybatis+Velocity+Maven demo

    Spring、SpringMVC、Mybatis、Velocity和Maven是Java Web开发中常用的一组技术栈,它们各自在软件开发的不同层面发挥着重要作用。...开发者可以通过分析和运行这个项目,深入理解这些框架的核心概念和实践应用。

    Velocity简介

    **源码分析** 对于熟悉Java的开发者来说,深入研究Velocity的源码可以帮助理解其工作原理。Velocity的源码结构清晰,主要包括以下几个关键组件: 1. `VelocityContext`: 用于存储和检索模板中使用的变量。 2. `...

Global site tag (gtag.js) - Google Analytics