Tomcat源碼深入——Servlet容器之外觀模式
來源:程序員人生 發布時間:2016-07-27 08:59:10 閱讀次數:2538次
之前1直很好奇Tomcat究竟是怎樣實現的,剛開始學的時候還不懂容器和服務器這些有甚么區分,Apache和Tomcat的區分及Web服務器,容器和利用服務器區分問題。直接看源碼的話感覺還是會覺得1頭霧水,本身就沒深入了解過的經驗,所以打算自己1邊看書1邊積累,有那個程度以后再看其他東西的源碼應當就有大體的思路了。
看的是《How Tomcat works》,中文版結合著看。
第1章是簡單的web服務器實現,簡單HTTP要求落后行返回,這個需要了解HTTP的要求和響應的組成。然后會使用Socket和ServerSocket就能夠摹擬簡單的實現。大概的思路就是HTTP要求后,解析后返回響應,閱讀器根據響應的格式返回特定的信息。
第2章是簡單的Servlet容器實現,對暫時處理靜態資源要求。現在增加對Servlet的要求處理。靜態資源的話就是直接讀取文件后返回。而Servlet的要求處理其實也沒有想象那末奇異,其實就是類加載器加載以后調用對應的方法。然后響應結果。
中文在這里翻譯有毛病,ServletProcessor1中,Request實現ServletRequest接口,Response實現ServletResponse接口。
所以Request和Response實例轉ServletRequest,ServletResponse都是向上轉型。翻譯是1上1下。
ServletProcessor1核心代碼:
URLClassLoader loader = new URLClassLoader(urls);
Class myClass = loader.loadClass(servletName);
servlet = (Servlet) myClass.newInstance();
servlet.service((ServletRequest) request,(ServletResponse) response);
ServletProcessor2核心代碼:
URLClassLoader loader = new URLClassLoader(urls);
Class myClass = loader.loadClass(servletName);
RequestFacade requestFacade = new RequestFacade(request);
ResponseFacade responseFacade = new ResponseFacade(response);
servlet = (Servlet) myClass.newInstance();
servlet.service((ServletRequest) requestFacade, (ServletResponse) responseFacade);
Request核心代碼
public class Request implements ServletRequest {
/* implementation of the ServletRequest*/
public Object dosth() {
dosth;
}
public Object myownmethod(){
}
}
RequestFacade核心代碼
public class RequestFacade implements ServletRequest {
private ServletRequest request = null;
public RequestFacade(Request request) {
this.request = request;
}
/* implementation of the ServletRequest*/
public Object dosth() {
return request.dosth();
}
}
ServletProcessor2的代碼要比ServletProcessor1好在哪里呢?
其實自己直接寫個例子程序更簡單
public interface Father {
public void say();
}
public class Son implements Father{
public void say(){
System.out.println("son");
}
public void sonmethod(){
System.out.println("father no");
}
}
public class SonDecade implements Father{
private Son son = null;
public SonDecade(Son son){
this.son = son;
}
public void say(){
son.say();
}
}
public class Test {
public static void main(String[] args) {
Son son = new Son();
Test.get((Father)son);
SonDecade sd = new SonDecade(son);
Test.get((Father)sd);
}
public static void get(Father f){
Son s = (Son)f;
//如果強迫向下轉型 Father為Son,那末可以調用到son的公共方法,這是不安全的, 又不能將public方法設為private
//由于其他類需要用到
s.sonmethod();
//所以使用外觀模式,雖然也能夠向下轉型,但是轉SonDecade,只能調用SonDecade的方法.而其中并沒有sonmethod方法。
SonDecade sd = (SonDecade)f;
}
}
同理,ServletProcessor1中,如果知道內部代碼實現的程序員
servlet.service((ServletRequest) request,(ServletResponse) response);
可以將ServletRequest實例再向下轉型為Request后調用其公共方法。就跟調用Son的sonmethod1樣,但是你的方法是給其他類使用的而不是給人這樣向下轉型后調用的話,可使用外觀模式將其去掉,其實跟1層皮1樣,遮掩了1些方法,里面還是不變的。
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈