之前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些方法,里面还是不变的。