深入理解TomcatPipeline和Valve_第1頁
深入理解TomcatPipeline和Valve_第2頁
深入理解TomcatPipeline和Valve_第3頁
深入理解TomcatPipeline和Valve_第4頁
深入理解TomcatPipeline和Valve_第5頁
已閱讀5頁,還剩6頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、深入理解Tomcat(四)Pipeline和Valve、,、刖百在上一小節(jié)我們簡單分析了一下Pipeline和Valve,并給出了整體的結(jié)構(gòu)圖。而這一節(jié),我們將詳細(xì)分析Tomcat里面的源碼。pipeline+valveValveValve作為一個個基礎(chǔ)的閥門,扮演著業(yè)務(wù)實際執(zhí)行者的角色。我們看看Valve這個接口有哪些方法。publicinterfaceValve/獲取下一個閥門publicValvegetNext();/設(shè)置下一個閥門publicvoidsetNext(Valvevalve);/后臺執(zhí)行邏輯,主要在類加載上下文中使用到publicvoidbackgroundProcess(

2、);/執(zhí)行業(yè)務(wù)邏輯publicvoidinvoke(Requestrequest,Responseresponse)throwsIOException,ServletException;/是否異步執(zhí)行publicbooleanisAsyncSupported();ContainedValveBase、Pipeline及其他相關(guān)組件都實現(xiàn)了Contained接口,我們看看這個接口有哪些方法。很簡單,就是get/set容器操作。publicinterfaceContained/*GetthelinkContainerwithwhichthisinstanceisassociated.returnT

3、heContainerwithwhichthisinstanceisassociatedornullifnotassociatedwithaContainer*/ContainergetContainer();/*SettheContainerwithwhichthisinstanceisassociated.paramcontainerTheContainerinstancewithwhichthisinstanceistobeassociated,ornulltodisassociatethisinstancefromanyContainer*/voidsetContainer(Conta

4、inercontainer);ValveBase從Valve的類層次結(jié)構(gòu),我們發(fā)現(xiàn)幾乎所有Valve都繼承了ValveBase這個抽象類,所以這兒我們需要分析一下它。Hierarchy:SubtypesofValveScope:aiiValve(orValveBase(org.apachexatalina.val1ClusterValve(org.apache.catalinaJJvmRouteBinderValve(org.apacReplicationValveorg.apache.caClusterSingleSignOn(org.apachValve類層次結(jié)構(gòu)publicabstrac

5、tclassValveBaseextendsLifecycleMBeanBaseimplementsContained,Valve/國際化管理器,可以支持多國語言protectedstaticfinalStringManagersm=StringManager.getManager(ValveBase.class);/InstanceVariables/無參構(gòu)造方法,默認(rèn)不支持異步publicValveBase()this(false);/有參構(gòu)造方法,可傳入異步支持標(biāo)記publicValveBase(booleanasyncSupported)this.asyncSupported=asyn

6、cSupported;/InstanceVariables/異步標(biāo)記protectedbooleanasyncSupported;/所屬容器protectedContainercontainer=null;/容器日志組件對象protectedLogcontainerLog=null;/下一個閥門protectedValvenext=null;/Properties/獲取所屬容器OverridepublicContainergetContainer()returncontainer;/設(shè)置所屬容器OverridepublicvoidsetContainer(Containercontainer)

7、this.container=container;/是否異步執(zhí)行OverridepublicbooleanisAsyncSupported()returnasyncSupported;/設(shè)置是否異步執(zhí)行publicvoidsetAsyncSupported(booleanasyncSupported)this.asyncSupported=asyncSupported;/獲取下一個待執(zhí)行的閥門OverridepublicValvegetNext()returnnext;/設(shè)置下一個待執(zhí)行的閥門OverridepublicvoidsetNext(Valvevalve)this.next=valv

8、e;/-PublicMethods/后臺執(zhí)行,子類實現(xiàn)OverridepublicvoidbackgroundProcess()/NOOPbydefault/初始化邏輯OverrideprotectedvoidinitInternal()throwsLifecycleExceptionsuper.initInternal();/設(shè)置容器日志組件對象到當(dāng)前閥門的containerLog屬性containerLog=getContainer().getLogger();/啟動邏輯Overrideprotectedsynchronizedvoidstartlnternal()throwsLifecy

9、cleExceptionsetState(LifecycleState.STARTING);/停止邏輯OverrideprotectedsynchronizedvoidstopInternal()throwsLifecycleExceptionsetState(LifecycleState.STOPPING);/重寫toString,格式為$containerNameOverridepublicStringtoString()StringBuildersb=newStringBuilder(this.getClass().getName();sb.append();if(container=n

10、ull)sb.append(Containerisnull);elsesb.append(container.getName();sb.append();returnsb.toString();/JMXandRegistration/設(shè)置獲取MBean對象的keyProperties,格式如:a=b,c=d,e=f.OverridepublicStringgetObjectNameKeyProperties()StringBuildername=newStringBuilder(type=Valve);Containercontainer=getContainer();name.append(

11、container.getMBeanKeyProperties();intseq=0;/PipelinemaynotbepresentinunittestingPipelinep=container.getPipeline();if(p!=null)for(Valvevalve:p.getValves()/Skipnullvalvesif(valve=null)continue;/Onlycomparevalvesinpipelineuntilwefindthisvalveif(valve=this)break;if(valve.getClass()=this.getClass()/Dupli

12、catevalveearlierinpipeline/incrementsequencenumberseq+;if(seq0)name.append(,seq=);name.append(seq);StringclassName=this.getClass().getName();intperiod=className.lastlndexOf(T);if(period=0)className=className.substring(period+1);name.append(,name=);name.append(className);returnname.toString();returnn

13、ame.toString();/獲取所屬域,從container獲取OverridepublicStringgetDomainInternal()Containerc=getContainer();if(c=null)returnnull;elsereturnc.getDomain();PipelinePipeline作為一個管道,我們可以簡單認(rèn)為是一個Valve的集合,內(nèi)部會對這個集合進(jìn)行遍歷,調(diào)用每個元素的業(yè)務(wù)邏輯方法oke()。是不是這樣呢?我們還是分析一下源碼,先看看接口定義。publicinterfacePipeline/Properties/獲取基本閥門publicValveget

14、Basic();/設(shè)置基本閥門publicvoidsetBasic(Valvevalve);/PublicMethods/添加閥門publicvoidaddValve(Valvevalve);/獲取閥門數(shù)組publicValvegetValves();/刪除閥門publicvoidremoveValve(Valvevalve);/獲取首個閥門publicValvegetFirst();/管道內(nèi)所有閥門是否異步執(zhí)行publicbooleanisAsyncSupported();/獲取管道所屬的容器publicContainergetContainer();/設(shè)置管道所屬的容器publicvoid

15、setContainer(Containercontainer);/查找非異步執(zhí)行的所有閥門,并放置至Result參數(shù)中,所以result不允許為nullpublicvoidfindNonAsyncValves(Setresult);StandardPipeline接著我們分析一下Pipeline唯一的實現(xiàn)StandardPipeline。代碼很長,但是都很簡單。publicclassStandardPipelineextendsLifecycleBaseimplementsPipeline,ContainedprivatestaticfinalLoglog=LogFactory.getLog

16、(StandardPipeline.class);/Constructors/構(gòu)造一個沒有所屬容器的管道publicStandardPipeline()this(null);/構(gòu)造一個有所屬容器的管道/構(gòu)造一個有所屬容器的管道publicStandardPipeline(Containercontainer)super();setContainer(container);/InstanceVariables*基本閥門,最后執(zhí)行的閥門*/protectedValvebasic=null;*管道所屬的容器*/protectedContainercontainer=null;*管道里面的首個執(zhí)行的閥

17、門*/protectedValvefirst=null;/PublicMethods/是否異步執(zhí)行,如果一個閥門都沒有,或者所有閥門都是異步執(zhí)行的,才返回rueOverridepublicbooleanisAsyncSupported()Valvevalve=(first!=null)?first:basic;booleansupported=true;while(supported&valve!=null)supported=supported&valve.isAsyncSupported();valve=valve.getNext();returnsupported;/查找所有未異步執(zhí)行的

18、閥門OverridepublicvoidfindNonAsyncValves(Setresult)Valvevalve=(first!=null)?first:basic;while(valve!=null)if(!valve.isAsyncSupported()result.add(valve.getClass().getName();valve=valve.getNext();/ContainedMethods/獲取所屬容器OverridepublicContainergetContainer()return(this.container);/設(shè)置所屬容器Overridepublicvoi

19、dsetContainer(Containercontainer)this.container=container;/初始化邏輯,默認(rèn)沒有任何邏輯OverrideprotectedvoidinitInternal()/NOOP/開始邏輯,調(diào)用所有閥門的start方法OverrideprotectedsynchronizedvoidstartInternal()throwsLifecycleExceptionStarttheValvesinourValvecurrent=first;if(current=null)current=basic;while(current!=null)if(curr

20、entinstanceofLifecycle)(Lifecycle)current).start();current=current.getNext();setState(LifecycleState.STARTING);/停止邏輯,調(diào)用所有閥門的stop方法Overrideprotectedsynchronizedvoidstoplnternal()throwsLifecycleExceptionsetState(LifecycleState.STOPPING);/StoptheValvesinourpipeline(includingthebasic),ifanyValvecurrent=

21、first;if(current=null)current=basic;while(current!=null)if(currentinstanceofLifecycle)(Lifecycle)current).stop();current=current.getNext();/銷毀邏輯,移掉所有閥門,調(diào)用removeValve方法OverrideprotectedvoiddestroyInternal()Valvevalves=getValves();for(Valvevalve:valves)removeValve(valve);/*重新toString方法*/Overridepublic

22、StringtoString()StringBuildersb=newStringBuilder(Pipeline);sb.append(container);sb.append();returnsb.toString();/PipelineMethods/獲取基礎(chǔ)閥門OverridepublicValvegetBasic()return(this.basic);/設(shè)置基礎(chǔ)閥門OverridepublicvoidsetBasic(Valvevalve)/ChangecomponentsifnecessaryValveoldBasic=this.basic;if(oldBasic=valve)r

23、eturn;/Stoptheoldcomponentifnecessary/老的基礎(chǔ)閥門會被調(diào)用stop方法且所屬容器置為nullif(oldBasic!=null)if(getState().isAvailable()&(oldBasicinstanceofLifecycle)try(Lifecycle)oldBasic).stop();catch(LifecycleExceptione)log.error(StandardPipeline.setBasic:stop,e);if(oldBasicinstanceofContained)try(Contained)oldBasic).setC

24、ontainer(null);catch(Throwablet)ExceptionUtils.handleThrowable(t);/Startthenewcomponentifnecessary/新的閥門會設(shè)置所屬容器,并調(diào)用start方法if(valve=null)return;if(valveinstanceofContained)(Contained)valve).setContainer(this.container);if(getState().isAvailable()&valveinstanceofLifecycle)try(Lifecycle)valve).start();c

25、atch(LifecycleExceptione)log.error(StandardPipeline.setBasic:start,e);return;/Updatethepipeline/替換pipeline中的基礎(chǔ)閥門,就是講基礎(chǔ)閥門的前一個閥門的hext指向當(dāng)前閥門Valvecurrent=first;while(current!=null)if(current.getNext()=oldBasic)current.setNext(valve);break;current=current.getNext();this.basic=valve;/添加閥門Overridepublicvoi

26、daddValve(Valvevalve)/ValidatethatwecanaddthisValve/設(shè)置所屬容器if(valveinstanceofContained)(Contained)valve).setContainer(this.container);/Startthenewcomponentifnecessary/調(diào)用閥門的start方法if(getState().isAvailable()if(valveinstanceofLifecycle)try(Lifecycle)valve).start();catch(LifecycleExceptione)log.error(St

27、andardPipeline.addValve:start:,e);/AddthisValvetothesetassociatedwiththisPipeline/設(shè)置閥門,將閥門添加到基礎(chǔ)閥門的前一個if(first=null)first=valve;valve.setNext(basic);elseValvecurrent=first;while(current!=null)if(current.getNext()=basic)current.setNext(valve);valve.setNext(basic);valve.setNext(basic);break;current=cur

28、rent.getNext();container.fireContainerEvent(Container.ADD_VALVE_EVENT,valve);/獲取閥門數(shù)組OverridepublicValvegetValves()ArrayListvalveList=newArrayList();Valvecurrent=first;if(current=null)current=basic;while(current!=null)valveList.add(current);current=current.getNext();returnvalveList.toArray(newValve0)

29、;/JMX方法,在此忽略publicObjectNamegetValveObjectNames()ArrayListvalveList=newArrayList();Valvecurrent=first;if(current=null)current=basic;while(current!=null)if(currentinstanceofJmxEnabled)valveList.add(JmxEnabled)current).getObjectName();current=current.getNext();returnvalveList.toArray(newObjectName0);/移除閥門OverridepublicvoidremoveValve(Valvevalve)Valvecurrent;if(first=valve)/如果待

溫馨提示

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

最新文檔

評論

0/150

提交評論