1. 程式人生 > >【FreeMarker】【程式開發】模板載入,模板快取

【FreeMarker】【程式開發】模板載入,模板快取

模板載入器

模板載入器是載入原生文字資料物件。這由具體的模板載入器物件來確定他們取得請求資料時使用了什麼樣的資料來源(資料夾中的檔案,資料等)。當呼叫cfg.getTemplate(Configuration cfg)時,FreeMarker詢問模板載入器是否已經為cfg建立返回給定模板路徑的文字,之後FreeMarker解析文字生成模板。

內建的模板載入器

在Configuration中可以使用下面的方法來建立三種模板載入(每種方法都會在其內部新建一個模板載入器物件,然後建立例項來使用):

void setDirectoryForTemplateLoading(File dir);
void setClassForTemplateLoading(Class cl, String prefix);
void setServletContextForTemplateLoading(Object servletContext, String path);

第一種方法在磁碟的檔案系統上設定了一個明確的目錄,它確定了從哪裡載入模板;FIle引數是一個存在的目錄,否則,將會丟擲異常。

第二種方法使用了一個Class型別的引數和一個字首。讓使用者指定什麼時候通過相同的機制來載入模板,用java的ClassLoader來載入類。傳入的Class引數會被用來呼叫Class.getResource()方法來找到模板。引數prefix是給模板的名稱來加字首的。在實際執行的環境中,類載入機制是首選用來載入模板的方法。

第三種方法需要Web應用的上下文和一個基路徑作為引數,這個基路徑是Web應用根路徑(WEB-INF目錄的上級目錄)的相對路徑。那麼載入器將會從Web應用目錄開始載入模板。儘管載入方法對沒打包的.war檔案起作用,因為它使用了ServletContext.getResource()方法來訪問模板。

從多個位置載入模板

如果需要從多個位置載入模板,那就為每個位置都例項化模板載入器物件,將它們包裝到一個MultiTemplateLoader的特殊模板載入器,最終將這個載入器傳遞給Configuration物件的setTemplateLoader(TemplateLoader loader)方法。

例如:

import freemarker.cache.*; // 模板載入器在這個包下
...
FileTemplateLoader ftl1 = new FileTemplateLoader(new File("/tmp/templates"));
FileTemplateLoader ftl2 = new FileTemplateLoader(new File("/usr/data/templates"));
ClassTemplateLoader ctl = new ClassTemplateLoader(getClass(), "");
TemplateLoader[] loaders = new TemplateLoader[] { ftl1, ftl2, ctl };
MultiTemplateLoader mtl = new MultiTemplateLoader(loaders);
cfg.setTemplateLoader(mtl);

FreeMarker將會嘗試從/temp/templates目錄載入模板,如果在這個目錄下沒有發現請求的模板,它就會繼續嘗試從/user/data/templates目錄下架子啊,如果還沒找到,就使用類載入器來載入模板。

從其他資源載入模板

如果內建的載入器都不適合使用,那麼就需要編寫自己的類載入器了,這個類需要實現freemarker.cacke.TemplateLoader介面,然後將它傳遞給Configuration物件的setTemplateLoader方法。

如果你的模板需要通過URL訪問其他模板,那麼就不需要實現TemplateLoader介面了,可以選擇子介面freemarker.cache.URLTemplateLoader來替代,只需實現getURL方法即可。

模板路徑

解析模板的路徑是由模板解析器來決定的。但是要和其他對路徑格式要求很嚴格的元件一起工作。

通常來說,強烈建議模板載入器使用URL風格的路徑。

在URL路徑中有其他含義時,那麼路徑中不要使用/, ./, ../ 和:// 。

模板快取

FreeMarker是會快取模板的。當呼叫getTemplate方法時,FreeMarker不但返回了Template物件的結果,而且還會將它儲存在快取中,當下一次再以相同路徑呼叫getTemplate方法時,那麼它只返回快取的Tempalte例項,而不會再次載入和解析模板檔案。

如果更改了模板檔案,當下次呼叫模板時,FreeMarker會自動重新載入和解析模板。

要檢查模板檔案是否改變內容了是需要時間的,有一個Configuration級別的設定被稱作“更新延遲”可以用來設定這個時間,預設是5秒。如果想要看到模板立即更新的效果,那麼就要把它設定為0.

此外,還可以使用Configuration物件的clearTemplateCache方法手動清空快取。

何時將一個被快取了的模板清除的應用策略是由配置的屬性cache_storage來確定的,通過這個屬性可以配置任何CacheStorage的實現。對於大多數用來來說,使用freemarker.cache.MruCacheStorage就足夠了。這個快取儲存實現了二級最近使用的快取。在第一級快取中,元件都被強烈引用到特定的最大數目。當超過最大數量時,最近最少使用的元件將被送至二級快取中。引用強度的大小可以由構造方法來指定。例如:設定強烈部分為20,輕微部分為250:

cfg.setCacheStorage(new freemarker.cache.MruCacheStorage(20, 250))


或者,使用MruCacheStorage昏村,它是預設快取儲存實現:

cfg.setSetting(Configuration.CACHE_STORAGE_KEY, "strong:20, soft:250");

當建立了一個新的Configuration物件時,它使用一個maxStrongSize值為0的MruCacheStorage快取來初始化,maxSoftSize的值是Integer.MAX_VALUE(也就是說在實際中,是無限大的)。但是使用非0的maxStrongSize對於高負載的伺服器來說也許是一個更好的策略。