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优化的文章
相关推荐
本指南将演示如何结合RNA Velocity分析使用已处理/标准化的Seurat对象。 请记住,尽管Seurat是基于R的,但是所有可用的RNA Velocity软件/软件包都是Python,因此我们将在两者之间来回移动。 我们将使用以下程序: ...
示例代码分析** `VelocityTest` 文件可能是项目中的主要源代码文件,它可能包含了初始化Velocity上下文、加载模板和渲染输出的过程。例如,它可能有以下代码片段: ```java VelocityContext context = new ...
### 源码分析 深入研究Velocity的源码有助于理解其工作原理,例如如何解析模板、如何执行指令、如何处理上下文对象等。这不仅可以帮助优化模板设计,还能为自定义扩展提供基础。 ### 学习资源 - 博文链接:...
- 使用Velocity Profiler工具进行性能分析和调试。 8. **最佳实践** - 学习如何编写可维护、可扩展的模板,避免模板过载,保持良好的代码组织。 9. **实际应用案例** - 书中可能会涵盖Velocity在邮件模板、报告...
通过分析这些文件,我们可以深入学习如何在实际项目中应用Maven和Velocity的整合。 总之,Maven和Velocity的整合提供了强大的项目管理和模板处理能力,使得Java Web应用的开发变得更加高效和灵活。通过理解和实践,...
10. **案例分析**:手册可能包含实际项目中的例子,帮助读者理解如何在不同场景下使用Velocity。 通过阅读这份中文手册,你可以深入了解Velocity的工作原理,掌握其使用技巧,从而在实际开发中更好地利用Velocity来...
### 实践案例分析 #### 八、Velocity 在实际项目中的应用 - **示例一:新闻系统**:在新闻系统中,使用 Velocity 渲染文章列表和详情页。 - **示例二:报表生成**:在企业应用中,使用 Velocity 生成各种报表,如...
Velocity.js 是velocity... 语法分析和模板渲染分离 基本完全支持velocity语法 浏览器使用支持模板之间相互引用,依据kissy模块加载机制 三个Helper,友好的数据模拟解决方案 Vim Syntax 标签:Velocity
**源码分析** 在深入学习Velocity时,查看源码是很有帮助的。`VelocityEngine`类是 Velocity 的核心,它负责初始化配置、加载模板以及执行模板合并。`VelocityContext`则用于存储模板中使用的变量。当你查看这些类的...
同时,分析`Vt`文件,可以掌握Velocity的配置与使用方法,这对于提升Java Web开发能力是非常有帮助的。 在实际应用中,Velocity常与Spring MVC、Struts等框架结合使用,构建MVC架构的Web应用。它可以帮助开发者专注...
由于没有具体的错误描述或代码示例,以上分析是基于VTL常见问题的一般性解答。在实际解决问题时,通常需要查看详细的日志、错误消息,或者阅读相关源代码来定位问题所在。如果在项目中遇到类似问题,建议查阅...
#### 二、Velocity的应用实例:MudStore案例分析 假设你是一家名为“MudStore”的在线商店的网页设计师,该店主要出售泥浆产品。为了提升用户体验,决定采用Velocity来实现个性化的页面展示。 - **客户个性化需求*...
四、实例分析 "PageList"可能是用于存储分页数据的一个类或者文件名,它可能包含了分页所需的信息,如当前页、总页数、每页数据等。在实际项目中,你可以创建一个PageList.java类,包含这些属性和方法,然后在...
本篇文章将对四个流行的Java模板引擎——Velocity、FreeMarker、Smarty4j以及HTTL进行效率分析,旨在探讨它们在处理业务逻辑编译和性能方面的优劣。 1. Velocity: Velocity是Apache软件基金会的一个开源项目,以其...
#### 四、示例场景分析 假设我们正在为一家名为“在线MUD商店”的企业开发一个电子商务网站。该网站需要展示各种类型的Mud产品,并且能够根据用户的购买历史推荐相应的产品。在这种情况下,Velocity可以帮助我们更...
Spring、SpringMVC、Mybatis、Velocity和Maven是Java Web开发中常用的一组技术栈,它们各自在软件开发的不同层面发挥着重要作用。...开发者可以通过分析和运行这个项目,深入理解这些框架的核心概念和实践应用。
**源码分析** 对于熟悉Java的开发者来说,深入研究Velocity的源码可以帮助理解其工作原理。Velocity的源码结构清晰,主要包括以下几个关键组件: 1. `VelocityContext`: 用于存储和检索模板中使用的变量。 2. `...