SpringMVC實現velocity多Resourceloader通過文件、數據庫等方式加載模版

Spring針對velocity實現了默認的file的resourceLoader,每次讀取的文件都是固定位置的,如果我們想實現隨時改變文件隨時頁面生效這種效果就很難實現了。

但是現實的應用場景中這樣的例子還不少,1營銷頁面,2產品化的配置管理等

實現方案,可以通過純前端的方式實現

比如:

1.把頁面模版寫在數據庫裏,然後寫死一個頁面,通過ajax從後臺取不同的模版,然後根據不同的數據做渲染展示

2.純後端模式實現,改造springmvc的view的render這層,保證每次渲染的時候,原有從文件系統讀模版改爲從db中讀模版。


本文主要採用第二種方案和大家做交流。


分析這個問題,首先要了解springMvc的DispatcherServlet處理鏈路

1. DispatcherServlet中獲取到controller返回的ModelAndView之後會通過render方法來獲取對應的view代碼如下:


2. resolveViewName()方法中,通過所有配置的viewResolver來進行resolveViewName。這個鏈路一直看下去,會到具體的viewResolver然後build出來view,這裏就不過多贅述,詳情看代碼。

3. 獲取到view之後,view會通過render()方法來做渲染,在渲染的過程中會通過VelocityView.doRender()來做渲染,然後通過getTemplate()獲取渲染需要的模版。

VelocityView.doRender()  ---->  getTemplate() ---->  VelocityEngine.getTemplate()  --->   RuntimeInstance.getTemplate()   --->   ResourceManager.getResource()   

重點看ResourceManager.getResource


該方法就是模版的具體獲取過程,如果第一次訪問,那麼走else分支,有了緩存走if分支,走else分支的會,會通過loader去獲取模版資源



可以看到最終判斷文件是否需要更新是通過loader來實現的,VelocityResourceLoader來加載具體的模版


看到這裏,我們可以明白了,控制velocity的模版獲取是通過loader來實現的。那麼如果我們想實現自己來從db裏面讀取模版,只需實現自己的loader即可(1.獲取模版,2控制何時更新模版)


但是問題來了!!!這個loader是何時spring給注入進去做的初始化呢?


繼續往下看

衆所周知spring配置velocity做展現層是通過VelocityConfigurer來實現的,VelocityConfigurer繼承自VelocityEngineFactory,通過各種參數實現了針對velocity的相關參數配置,主要的方法有:VelocityEngineFactory.initVelocityResourceLoader()


spring寫死了默認的loader名稱爲file

看到這裏大家應該比較清楚了,實現從db裏面讀取vm文件,我們只需要重寫兩個類即可

1.ResourceLoader(在loader中實現原有的從文件系統中讀取改爲從db中或者分佈式文件系統中讀取,並控制velocity的緩存管理,實現自己來管理這部分模版的緩存)

2.VelocityConfigurer(在初始化velocity的時候設置不同的classloader名稱,並且將自己新寫的ResourceLoader設置進去即可)


思路基本上就是上面的思路,由於公司代碼不能漏出,所以暫時不貼出重寫後的類了。

後續會在上幾篇博客嵌入了jetty的springMvc空框架上進行實現。敬請期待。


這篇文章也是斷斷續續靠晚上擠出來的一點點時間完成的。感覺工作忙了越來越沒寫技術博客的動力了,無奈記性太差,怕下次忘掉,又要翻源碼,所以就記錄一下思路吧。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章