淺談JSP是如何編譯成servlet并提供服務(wù)的_第1頁
淺談JSP是如何編譯成servlet并提供服務(wù)的_第2頁
淺談JSP是如何編譯成servlet并提供服務(wù)的_第3頁
淺談JSP是如何編譯成servlet并提供服務(wù)的_第4頁
淺談JSP是如何編譯成servlet并提供服務(wù)的_第5頁
已閱讀5頁,還剩1頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

第淺談JSP是如何編譯成servlet并提供服務(wù)的privatevoidserviceJspFile(HttpServletRequestrequest,HttpServletResponseresponse,StringjspUri,booleanprecompile)throwsServletException,IOException{

JspServletWrapperwrapper=this.rctxt.getWrapper(jspUri);

if(wrapper==null){

synchronized(this){

wrapper=this.rctxt.getWrapper(jspUri);

if(wrapper==null){

if(null==this.context.getResource(jspUri)){

this.handleMissingResource(request,response,jspUri);

return;

wrapper=newJspServletWrapper(this.config,this.options,jspUri,this.rctxt);

this.rctxt.addWrapper(jspUri,wrapper);

try{

//核心服務(wù)方法

wrapper.service(request,response,precompile);

}catch(FileNotFoundExceptionvar8){

this.handleMissingResource(request,response,jspUri);

}

然后進(jìn)入JspServletWrapper.service方法(部分代碼):

//注意這個(gè)reload是volatile修飾的

privatevolatilebooleanreload=true;

publicvoidservice(HttpServletRequestrequest,HttpServletResponseresponse,booleanprecompile)throwsServletException,IOException,FileNotFoundException{

Servletservlet;

try{

if(this.ctxt.isRemoved()){

thrownewFileNotFoundException(this.jspUri);

//判斷development模式和firstTime(首次請(qǐng)求)

if(!this.options.getDevelopment()!this.firstTime){

if(pileException!=null){

throwpileException;

}else{

synchronized(this){

this.firstTime=false;

//調(diào)用JspCompilationCpile方法

pile();

//獲取最終提供服務(wù)的servlet

servlet=this.getServlet();

if(precompile){

return;

try{

//根據(jù)是否實(shí)現(xiàn)SingleThreadModel決定是否需要做同步控制

if(servletinstanceofSingleThreadModel){

synchronized(this){

servlet.service(request,response);

}else{

servlet.service(request,response);

}

這里主要看JspCompilationCplie方法:

publicvoidcompile()throwsJasperException,FileNotFoundException{

this.createCompiler();

if(this.jspCompiler.isOutDated()){

if(this.isRemoved()){

thrownewFileNotFoundException(this.jspUri);

try{

//清楚文件數(shù)據(jù)

this.jspCompiler.removeGeneratedFiles();

//置空jspLoader,現(xiàn)在置null,后面就會(huì)創(chuàng)建一個(gè)新的JspLoader

this.jspLoader=null;

//根據(jù)jsp生成servlet的邏輯,實(shí)現(xiàn)主要有AntCompiler和JDTCompiler,默認(rèn)JDTCompiler

this.jspCpile();

//設(shè)置reload為true,后面根據(jù)reload參數(shù)判斷是否需要重新加載

this.jsw.setReload(true);

this.jsw.setCompilationException((JasperException)null);

}

要注意對(duì)于isOutDated方法的判斷,并不是簡單地每次請(qǐng)求都檢查jsp文件是否更新,而是有一個(gè)間隔時(shí)間,如果此次檢查更新的時(shí)間在上一次檢查更新+間隔時(shí)間之內(nèi),也就是沒有超過間隔時(shí)間,那么就不會(huì)去檢查jsp文件的更新。這就是我們說的jsp熱更新延時(shí)生效,isOutDated是Compiler的方法,如下(部分代碼):

publicbooleanisOutDated(booleancheckClass){

if(this.jsw!=nullthis.ctxt.getOptions().getModificationTestInterval()0){

//getModificationTestInterval就是檢查最短間隔時(shí)間,單位為秒

if(this.jsw.getLastModificationTest()+(long)(this.ctxt.getOptions().getModificationTestInterval()*1000)System.currentTimeMillis()){

returnfalse;

this.jsw.setLastModificationTest(System.currentTimeMillis());

LongjspRealLastModified=this.ctxt.getLastModified(this.ctxt.getJspFile());

if(jspRealLastModified0L){

returntrue;

}else{

longtargetLastModified=0L;

FiletargetFile;

if(checkClass){

targetFile=newFile(this.ctxt.getClassFileName());

}else{

targetFile=newFile(this.ctxt.getServletJavaFileName());

if(!targetFile.exists()){

returntrue;

}else{

targetLastModified=targetFile.lastModified();

if(checkClassthis.jsw!=null){

this.jsw.setServletClassLastModifiedTime(targetLastModified);

if(targetLastModified!=jspRealLastModified){

if(this.log.isDebugEnabled()){

this.log.debug("Compiler:outdated:"+targetFile+""+targetLastModified);

returntrue;

}elseif(this.jsw==null){

returnfalse;

}

另外,這里還涉及到JSP的編譯工作,編譯工作主要由piler.Compiler編譯器負(fù)責(zé),Compiler是一個(gè)抽象類,apache-jsp中提供了兩種實(shí)現(xiàn):AntCompiler和JDTCompiler,默認(rèn)使用的編譯器為JDTCompiler。

最后回到JspServletWrapper.getServlet方法:

privatevolatilebooleanreload=true;

publicServletgetServlet()throwsServletException{

//reload是被volatile修飾的一個(gè)boolean變量

//這里進(jìn)行雙重檢測(cè)

if(this.reload){

synchronized(this){

if(this.reload){

//需要重載

this.destroy();

Servletservlet;

try{

InstanceManagerinstanceManager=InstanceManagerFactory.getInstanceManager(this.config);

//創(chuàng)建一個(gè)新的serlvet實(shí)例對(duì)象,注意這里的getJspLoader方法

servlet=(Servlet)instanceManager.newInstance(this.ctxt.getFQCN(),this.ctxt.getJspLoader());

}catch(Exceptionvar6){

Throwablet=ExceptionUtils.unwrapInvocationTargetException(var6);

ExceptionUtils.handleThrowable(t);

thrownewJasperException(t);

servlet.init(this.config);

if(!this.firstTime){

this.ctxt.getRuntimeContext().incrementJspReloadCount();

this.theServlet=servlet;

this.reload=false;

returnthis.theServlet;

}

可以看到,方法中使用了雙重檢測(cè)機(jī)制判斷是否需要重載,reload參數(shù)由volatile修飾保證可見性。在創(chuàng)建新的servlet實(shí)例的時(shí)候,classLoader是通過JspCompilationContext.getJspLoader方法獲取的,看看這個(gè)方法的邏輯:

publicClassLoadergetJspLoader(){

if(this.jspLoader==null){

this.jspLoader=newJasperLoader(newURL[]{this.base

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論