javascript
JSP 热部署 源码解析
概述
我們知道在開發(fā)工程的時候jsp文件是即修改即生效的。Tomcat jsp熱部署的實現(xiàn)原理是每個JSP頁面從上次訪問到下次訪問總是有默認幾秒的緩存時間的,也就說并不是嚴格的即修改即生效,tocmat7默認是有4秒的緩存延遲的。這個默認的緩存延遲是在類 EmbeddedServletOptions 的 private intmodificationTestInterval = 4; 這個屬性定義的。如果過了4秒緩存時間即失效,這個時候tomcat就會讀取jsp的modified時間戳和work目錄下編譯好的class文件的modified的時間戳作對比。如果相等則class文件沒有過期,則不會重新編譯jsp文件,如果過期了則重新將jsp編譯成java,并進一步編譯成class。同時創(chuàng)建一個新的JasperLoader來重新加載這個有jsp編譯好的class文件。
熱部署原理
一個class只能由classloader加載一次,如果再次加載將會導致類沖突。但是JVM表示一個類是否是同一個類有兩個條件。
1. 看這個類的完整類名是否一樣(包名和類名)
2. 加載這個類的ClassLoader是否是同一個,也就是說這個ClassLoader是否是同一個實例。
如果是同一個ClassLoader的不同的實例加載同一個類,那么就可以實現(xiàn)熱更新部署了。
下面具體分析一下這個過程:
JspServlet.serviceJspFile() 方法
1. 判斷當前jsp頁面的JspServletWrapper對象是否存在,如果不存在,則創(chuàng)建并存放到 jsps緩存中。
2.調用JspServletWrapper.service() 方法
JspServletWrapper.service() 方法
1. 判斷該jsp是否刪除
2. 判斷該 jsp 是否可用
3. 判斷當前項目是不是development模式運行,如果是則每次都執(zhí)行JspCompilationContext.compile() 方法
4. 判斷是否是首次請求,如果首次請求則也執(zhí)行JspCompilationContext.compile() 方法。
development 模式配置
JspServlet 模式是development模式,可以通過web.xml中把development模式關閉 development=false
JspCompilationContext.compile() 方法
1. 根據(jù)class文件(或java文件,通過一個參數(shù)可以選擇)的最后修改時間,判斷文件是否更新過,如果更新過,
2. 刪除之前編譯過的文件信息
3. 把jspLoader置空,需要重新創(chuàng)建一個ClassLoader,來達到熱加載的目的。
4. 調用Compiler.compile()重新把jsp轉換成servlet,并編譯servlet成class文件。
5. 把JspServletWrapper.reload 修改為true。后面getServlet() 根據(jù)這個參數(shù)判斷是否重新加載該servlet。
Compiler.isOutDated()方法
判斷上次請求的時候+4秒的時候,是否大于當前時間,也就是說,距離上次檢查文件更新時間是否有4秒的時間,如果小于4秒則不進行檢查文件是否更新,不重新加載編譯jsp文件。
根據(jù)上次最后修改時間,和這次獲得的文件最后修改時候做對比,來判斷文件是否更新過。
ctxt.getOptions().getModificationTestInterval() 默認的時間為4秒
Compiler.compile() 方法
1. 把jsp文件轉換成java(servlet)文件
2. 把java文件編譯成class文件。
JspServletWrapper.getServlet() 方法
1. 通過reload判斷是否需要重新加載Servlet
2. 如果需要重新加載,則先銷毀之前的Servlet
3. ctx.getJspLoader() 當前這個ClassLoader在上面已經(jīng)賦值為null,在這個方法里又重新創(chuàng)建了一個Classloader實例
4. 初始化新創(chuàng)建的Servlet
5. 把reload賦值為 false
getJspLoader() 方法
調用Servlet.service() 方法
在JspServlet.serviceJspFile() 方法 獲取Jsp對應的Servlet實例后,然后調用Servlet的Service方法。
本人簡書blog地址:http://www.jianshu.com/u/1f0067e24ff8????
點擊這里快速進入簡書
GIT地址:http://git.oschina.net/brucekankan/
點擊這里快速進入GIT
總結
以上是生活随笔為你收集整理的JSP 热部署 源码解析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Tomcat WebappClassLo
- 下一篇: gradle idea java ssm