Configuration 是一个存放应用级别(application level)公共配置信息,以及模版(Template)可使用的全局共享变量的一个对象。同时它还负责模版(Template)实例的创建以及缓存。Configuration 实际上是freemarker.template.Configuration 对象的实例,使用其构造函数创建。通常应用使用一个共享的单实例Configuration 对象。
Configuration 对象可被Template 对象的方法使用,每一个模版实例都关联与一个Configuration 实例,它是通过Template 的构造函数被关联进去的,通常是你使用这个方法来Configuration.getTemplate 获得模版对象的。
共享变量:
配置信息:
spring框架中配置:
template不需要做什么配置:
Environment层:这里有两种配置方法
freemarker配置:
1.在3层中freemarker.core.Configurable的setter配置
2.在Confiuration层
freemarker.template.Configuration的setter方法
3.在3层中可用String 键-值对书写的
freemarker.core.Configurable.setSetting(String,String)
4只在Configuration
freemarker.template.Configuration.setSetting(String,String)
模版加载器:
模版加载器
模版加载器是基于抽象路径("index.ftl"或"products/catalog.ftl")加载原始数据的那些对象,
而究竟加载何种资源(目录中的文件数据还是数据库中的数据)取决于具体的加载器实现。
当你调用cfg.getTemplate 时,FreeMarker 将会询问你之前配置给Configuration 对象的模版加载器,
有该模版加载器负责文件的载入。
内建的模版加载器
你可以用以下三个方法来设置模版加载的三种方式
void setDirectoryForTemplateLoading(File dir);
或者
void setClassForTemplateLoading(Class cl, String prefix);
或者
void setServletContextForTemplateLoading(Object servletContext, String path);
以上第一种方式显示的指定了一个文件系统中的目录,
FreeMarker 将会在此目录记载模版,
不用说,此目录必须存在,否在会抛出异常。
第二种方式以一个Class作为一个输入参数,当你想使用ClassLoader的方式来加载模版的时候,
你就可以使用这种方式,这种方式将会调用来寻找模版文件,
同时这种模版加载的方式要比前一种稳定一些尤其是在生产系统中。
你可以很容易的把资源文件,以及图标等打包到.jar 文件中。
第三种方式把web 应用的上下文以及基路径(相对与WEN-INF 的父路进来说)作为参数。
该种方式的模版加载器将会从web 应用上下文种加载模版。
从多个位置加载模版:
FreeMarker 将会首先在路径/tmp/templates中搜索模版文件,
如果没有找到那么回到路径/usr/data/templates中搜索,
如果还没有找到,那么则会尝试用class-loader的方式加载。
从其他资源中获取模版文件
如果在这些内建的模版加载器中没有一个符合你的要求,那么你可以自己定制一个模版加载器,
只需要实现freemarker.cache.TemplateLoader 接口就可以了,
然后通过方法setTemplateLoader(TemplateLoader loader)把其传递给Configuration对象。
缓存模版
FreeMarker缓存模版的意思就是,当你通过getTemplate方法获取一个模版的时候,FreeMarker不仅会返回一个Template对象,而且会缓存该对象,当你下一次以相同的路径请求模版的时候,它就会返回缓存中的模版对象。如果你改变了模版文件,那么当你下一次获取模版的时候,FreeMarker会自动重新加载,重新解析模版。虽然如此,但是如果直接判断一个文件是否修改过是一个耗时的操作,那么FreeMarker 在Configuration 对象级别提供了一个配置参数“update delay”。该参数的意思是FreeMarker多长时间去判断一次模版的版本,默认设置是5秒钟,也就是每个5秒就会判断模版是否经过修改,如果你想实时的判断,那么设置该参数为0。另外一点需要注意,并不是所有的加载器都支持这种判断方式,举例来说基于class-loader 的模版加载器就不会发现你修改过模版文件。
对于删除缓存中的模版FreeMarker 是这么做的,你可以使用Configuration 对象方法clearTemplateCache 以手工的方式清楚缓存中的模版对象。而实际上缓存部分可以作为一个组建加入到FreeMarker 中(也就是它可以使用第三方缓存方案)你可以通过设置cache_storage 这个参数来实现。对大多数开发者来FreeMarker 自带的freemarker.cache.MruCacheStorage 实现已经足够了。这个缓存使用2 个级别的Most Recently Used(最近最多用)策略。在第一个级别,所有的缓存条目都是使用强引用(strongly referenced:条目并不会被JVM 所清楚,与其相对的弱引用softly reference)直到达到最大时间,那些最近最少使用的条目就会被迁移到二级缓存。在这个级别条目都是使用弱引用直到达到过期。若引用与强引用的区域的大小是可以在构造函数中设置的,例如你想把强引用区域设置为20,弱引用区域设置为250,那你可以使用以下代码:
cfg.setCacheStorage(new freemarker.cache.MruCacheStorage(20, 250))
由于MruCacheStorage 是默认的缓存实现,那么你也可以这样设置:
cfg.setSetting(Configuration.CACHE_STORAGE_KEY,"strong:20, soft:250");
当你创建一个新的Configuration时,其默认使用MruCacheStorage缓存实现且默认的值maxStrongSize等于0,maxSoftSize等于Integer.MAX_VALUE(也就是理论最大值)。但是对于高负荷的系统来说,我们建议maxStrongSize 设置成一个非0 的数值,不然会导致频繁的重新加载,重新解析模版。
可能产生的异常
FreeMarker 产生的异常一般可归以下几类:
FreeMarker 初始化阶段产生的异常: 通常在你的应用中仅需要初始化FreeMarker 一次,而当在这个时间段类产生的异常就叫做初始化异常。
加载解析模版期的异常:当你通过Configuration.getTemplate()方法获取模版的时候(如果模版之前没有被缓存),将会产生两类异常:
- IOException:由于模版没有找到,或在读取模版的时候发生其他的IO异常,比如你没有读取该文件的权限等等;
- freemarker.core.ParseException 由于模版文件的语法使用不正确;
执行期间的异常:当你调用Template.process(...)方法的时候,会抛出两类异常:
- IOException 往输出写数据时候发生的错误;
- freemarker.template.TemplatException其他运行期产生的异常,比如一个最常见的错误就是模版引用了一个不存在的变量;