這篇文章主要介紹了 Jasper的自動檢測實現的機制比較簡單,依靠某後臺線程不斷檢測JSP文件與編譯後的class文件的最後修改時間是否相同,若相同則認爲沒有改動,但假若不一樣則須要從新編譯,須要的朋友能夠參考下java
jsp 自動編譯機制詳細介紹tomcat
總的來講,Jasper的自動檢測實現的機制比較簡單,依靠某後臺線程不斷檢測JSP文件與編譯後的class文件的最後修改時間是否相同,若相同則認爲沒有改動,但假若不一樣則須要從新編譯。實際上因爲在Tomcat部署的項目的JSP可能引入了其餘頁面,或者引入了其餘jar包,並且這些資源均可能是遠程的資源,因此實際處理會比較複雜,一樣要遍歷檢測這些引入的不一樣資源是否作了修改。架構
上圖是一個形象的示意圖,咱們知道Tomcat架構中有四個級別的容器,Engine、Host、Context和Wrapper,而jsp編譯對應在wrapper級別,因此經過StandardWrapper不斷執行任務去調用jasper,而jasper則不斷檢測校驗本地和遠程的各類資源,一旦發現須要從新編譯則進行重編譯。往下看看具體如何實現。app
首先,須要一個後臺執行線程,Tomcat中有專門的一條線程處理不一樣容器的background任務,想在不一樣的容器中執行某些後臺任務只需重寫backgroundProcess方法便可實現,因爲JspServlet對應於Wrapper級別,因此要在StandardWrapper中重寫backgroundProcess,它會調用實現了PeriodicEventListener接口的Servlet,其中JspServlet就實現了PeriodicEventListener接口,此接口只有一個periodicEvent方法,具體的檢測邏輯在此方法中實現便可。jsp
其次,檢測判斷從新編譯的根據是什麼?從新編譯就是再次把jsp變成Java再變成class,而觸發這個動做的條件就是當咱們修改了某個jsp文件後,或者某jsp文件引入的資源被修改後,都將觸發從新編譯動做,因此最好的判斷依據就是某jsp或資源的最後修改時間lastmodified屬性,正常順序是jsp通過編譯後生成class文件,把此class文件的lastmodified屬性設置成jsp文件的lastmodified,此時兩個文件的lastmodified屬性是相同的,當咱們改了jsp文件保存後,jsp的lastmodified屬性就被置爲當前時間,此時經過判斷兩個文件的lastmodified屬性決定是否從新編譯。從新編譯後jsp與class文件的lastmodified屬性再次被置爲相同。對於引入的資源,內存中維護了上次編譯時引入資源的lastmodified屬性,不斷獲取引入資源的lastmodified屬性並與內存中對應的lastmodified屬性進行比較,一樣能夠很容易判斷是否須要從新編譯。spa
最後,對於本地和遠程資源分別如何檢測?對於本地資源來講,使用java.io.File類能夠很方便的實現對某JSP文件或其餘文件的lastmodified屬性讀取。對於遠程資源,好比jar包,爲了方便處理jar包含的屬性,使用java.NET.URL能夠很方便操做,它包含了不少協議,例如常見的jar、file、ftp等協議,使用至關方便,.net
?線程
1code 2htm 3 |
|
只需三步即完成對遠程jar包的讀取且取出最後修改時間。固然URL還支持本地文件資源的讀取,因此它是很好的資源讀取抽象對象,Tomcat中對引入資源的管理都是使用URL做爲操做對象。
本小節探討了Jasper自動檢測機制的實現,自動檢測機制給咱們的開發帶來了很好的體驗,咱們沒必要本身修改了jsp後本身去執行編譯操做,而是tomcat經過jasper幫咱們定時檢測編譯操做。
感謝閱讀,但願能幫助到你們,謝謝你們對本站的支持!