StandardHost及UML類圖:
?
1、StandardHost類是Host接口的默認實現;其繼承自ContainerBase類,說明他也是一個容器類,既然是容器類,那肯定也有管道對象PipeLine和閥門,其基礎閥門(Basic Valve)的實現類是org.apache.catalina.core.StandardHostValve,ErrorReportValve和ErrorDispatcherValve類作為管道對象中的錯誤處理閥門;
2、當客戶端的請求Request要在Host中查找到相應的Context處理請求時,就需要使用mapper對象處理,StandardHost中的mapper實現類是org.apache.catalina.core.StandardHostMapper;當ContainerBase.start啟動時會調用addDefaultmapper添加默認的映射器,也就會調用到StandardHost.addDefaultmapper方法:
?
此處的mapperClass的內容就是org.apache.catalina.core.StandardHostMapper;
3、StandardHost繼承自ContainerBase類,也就實現了LifeCycle接口,在其start方法中將ErrorReportValve和ErrorDispatcherValve閥門添加到管道對象中,在其invoke方法調用中總是先調用Basic Valve后再調用PipeLine中的閥門:
?
4、在ApplicationContext的getResource方法中會去獲取資源路徑,其中就使用到了Host的getName方法,因此Context至少要配置一個Host(除非自己重新實現一個ContextConfig對象);
?
Standardhost處理請求流程:
1、客戶端的請求Request在Connector中封裝好后傳遞給StandardHost.invoke方法,由于StandardHost沒有實現invoke方法,因此invoke會調用到其父類ContainerBase.invoke方法,然后調用管道對象里面的基礎閥門StandardHostValve.invoke方法;
2、StandardHostValve.invoke調用StandardHost.map(request, update)方法,由于StandardHost沒有實現這個原型的map方法,因此調用了ContainerBase.map方法,在ContainerBase.map中根據協議類型(http)查找到對應的mapper對象(findMapper查找時,由于Standardhost中已經將StandardHostMapper作為默認mapper對象添加到Host中,因此findMapper會返回該mapper對象);
3、StandardHostMapper.map方法基本沒做什么處理,獲取到Request的URI信息后就到StandardHost中去查找對應的Context對象(findChild),StandardHost.children變量中存儲了ContextName和Context對象的映射關系,而Context.name屬性就是取的該Context.path屬性,因此在StandardHost.map方法中直接拿路徑到children中取查找對應的Context對象:
?
4、在StandardHost中查找到對應的Context后,直接調用Context.invoke方法交由Context對象去處理;
StandardEngine及UML類圖:
?
1、Engine容器也就是tomcat的servlet引擎,StandardEngine類是Engine接口的默認實現;當部署tomcat時需要支持多個虛擬機的話,就需要使用engine容器,事實上,一般情況下,部署的tomcat都會使用一個Engine容器;
2、StandardEngineValve類作為StandardEngine類的基礎閥門(Basic Valve),其invoke方法負責查找出對應的Host出來并交由host處理;
StandardEngine處理請求流程:
?
1、與上面的StandardHost的請求處理相同,客戶端請求Request到達StandardEngine.invoke,再到達ContainerBase.invoke,最后到達StandardEngineValve閥門的invoke方法,在這里調用Engine.map方法,由于StandardEngine沒有實現map方法,因此傳遞到了ContainerBase的map方法中,首先調用findMapper查找映射器,由于StandardEngine實現了addDefaultMapper方法添加默認的映射器StandardEngineMapper,因此findMapper會返回StandardEngineMapper映射器實例;
2、在StandardEngineMapper.map方法里面,首先根據請求Request獲取到HostName,然后在根據HostName查找得到對應的Host對象;
?
可以看到在查找Host時,首先根據HostName在Children的哈希表中查找名稱為HostName的Host對象,如果沒有查找到,則判斷遍歷所有Host對象,如果有Host對象的別名與HostName相同,則返回該Host實例,如果這樣還沒找到,則直接返回默認Host對象處理;
3、得到Host對象后將請求直接轉給Host.invoke處理;