Tomcat源码深入——Servlet容器之外观模式

来源:互联网 发布:广州php招聘 编辑:程序博客网 时间:2024/05/01 19:58

之前一直很好奇Tomcat究竟是怎么实现的,刚开始学的时候还不懂容器和服务器这些有什么区别,Apache和Tomcat的区别及Web服务器,容器和应用服务器区别问题。直接看源码的话感觉还是会觉得一头雾水,本身就没深入了解过的经验,所以打算自己一边看书一边积累,有那个程度之后再看其他东西的源码应该就有大体的思路了。

看的是《How Tomcat works》,中文版结合着看。


第一章是简单的web服务器实现,简单HTTP请求后进行返回,这个需要了解HTTP的请求和响应的组成。然后会使用Socket和ServerSocket就可以模拟简单的实现。大概的思路就是HTTP请求后,解析后返回响应,浏览器根据响应的格式返回特定的信息。


第二章是简单的Servlet容器实现,对暂时处理静态资源请求。现在增加对Servlet的请求处理。静态资源的话就是直接读取文件后返回。而Servlet的请求处理其实也没有想象那么神奇,其实就是类加载器加载之后调用对应的方法。然后响应结果。


中文在这里翻译有错误,ServletProcessor1中,Request实现ServletRequest接口,Response实现ServletResponse接口。
所以Request和Response实例转ServletRequest,ServletResponse都是向上转型。翻译是一上一下。


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的sonmethod一样,但是你的方法是给其他类使用的而不是给人这样向下转型后调用的话,可以使用外观模式将其去掉,其实跟一层皮一样,遮掩了一些方法,里面还是不变的。

0 0