How Tomcat Works读书笔记2

我们回顾一下,第一章实现的Web服务器类图大致如下:

其中HttpServer中的await()方法会使用一个ServerSocket来监听8080端口,用来接收客户端的请求。当接收到用户请求后会创建一个Socket对象,通过与Socket关联的InputStream来创建并填充一个Request对象(这里只是简单的填充了Uri)。然后用Socket关联的OutputStream创建一个Response对象,并持有一个Request对象。最后通过调用Response对象中的sendStaticResource()方法来向客户端发送静态页面(其中根据request.getUri()来决定返回哪个页面)。

而第二章实现的Web服务器有什么改进的地方?

首先摒弃了第一章中自定义的ResponseRequest类,而是根据Servlet标准提供的接口来定义类。Servlet 编程是通过 javax.servletjavax.servlet.http 这两个包的类和接口来实现的。其中一个至关重要的就是javax.servlet.Servlet 接口了。所有的 servlet 必须实现实现或者继承实现该接口的类。Servlet接口有五个方法:


public interface Servlet {

    public void init(ServletConfig config) throws ServletException;

    public ServletConfig getServletConfig();

    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException;

    public String getServletInfo();

    public void destroy();
}

其中initservicedestoryServlet的生命周期方法。init只会在Servlet实例化完成后被调用一次,service会在每次请求该Servlet时被调用,而destory会在该Servlet卸载时被调用,这通常发生在Servlet容器正在被关闭或者Servlet容器需要一些空闲内存的时候。

在第二章中实现的Web服务器将会以Servlet容器的角度来编程。总的来说,一个全功能的Servlet容器会为servlet的每个HTTP请求做下面一些工作:

  • 当第一次调用Servlet的时候,加载该Servlet类并调用Servletinit方法(仅一次)
  • 对每次请求,构造一个javax.servlet.ServletRequest实例和一个javax.servlet.ServletResponse实例
  • 调用servletservice方法,并传入ServletRequestServletReponse实例
  • servlet容器被关闭时,调用servletdestory方法并卸载servlet

那么如何加载Servlet类呢,我们可以用

Class.forName(xxx)

来加载一个类。也可以用java.net.URLClassLoader类,它是java.lang.ClassLoader类的一个直接子类。拥有一个URLClassLoader实例,那么就可以直接使用它的loadClass方法去加载Servlet类了。这里我们就直接用URLClassLoader最简单的构造函数:URLClassLoader(URL[] urls),这里的URL数组就指定了类所在的目录位置(通常叫repository)。不过由于双亲加载机制,如果在classpath下已经存在某个类,就加载不到repository中的对应类了。

刚才说了这里会摒弃第一章的RequestResponse类。而新的RequestResponse类分别实现了 javax.servlet.ServletRequest接口和javax.servlet.ServletResponse接口,只不过在目前很多方法都留空了。第二章的类图大致如下:

HttpServer依旧监听8080端口等待客户端连接,根据请求内容创建并填充Request对象,并创建Response对象。RequestResponse类中的大多数方法都是留空的。然后会根据请求内容来判断是创建ServletProcessor实例还是创建StaticResourceProcessor实例,对了,这里的话我个人觉得在两个Processor之上再创建一个Processor接口并让它们实现这个接口更加好一些。如果是StaticResourceProcessor,那么直接返回请求的静态内容。而如果是ServletProcessor,那么则去加载请求的Servlet类,然后调用ServletdoService方法来进行处理并响应给客户端。

时间: 2024-11-05 07:40:22

How Tomcat Works读书笔记2的相关文章

how tomcat works 读书笔记(二)----------一个简单的servlet容器

app1 (建议读者在看本章之前,先看how tomcat works 读书笔记(一)----------一个简单的web服务器 http://blog.csdn.net/dlf123321/article/details/39378157) 回顾我们上一章,我们开发了一个最最简单的web服务器,它可以使用户访问服务器内的静态资源.当然这是远远不够的,在这一节里,我们就试着让服务器在能相应静态资源的基础上继续支持servlet. servlet接口 javax.servlet.Servlet接口

how tomcat works 读书笔记四 tomcat的默认连接器

其实在第三章,就已经有了连接器的样子了,不过那只是一个学习工具,在这一章我们会开始分析tomcat4里面的默认连接器. 连接器 Tomcat连接器必须满足以下几个要求 1 实现org.apache.cataline.Connector接口 2 负责创建实现了org.apache.cataline.Request接口的request对象 3 负责创建实现了org.apache.cataline.Response接口的response对象 这里默认的连接器的原理很简单,就是等待http请求,创建re

How tomcat works 读书笔记十七 启动tomcat 上

一路跋山涉水,这是最后一章了. 关于tomcat的启动,有两个类,一个是Catalina类,一个是Bootstrap类. 理论上,两个类可以和到一起,但是为了支持多种运行模式,又把他们分开了. 为了让用户更方便的启动tomcat,还有批处理文件startup.bat(终于见到最顶层的模块了!!) Catalina 先说Catalina 它里面有一个Server组件(不懂的看第14章).同时在它的start方法中包含一个Digester对象(不懂的看第15章)用来解析conf/下的Server.x

How tomcat works 读书笔记十七 启动tomcat 下

在上一节中,我们程序的起始位置还是Bootstrap,现在我们通过bat文件来启动这个类. 在分析catalina.bat之前,我们先看看几个简单的我们能用到的dos命令. 基础知识 1 rem 注释,解释器不会执行rem开始的命令 2 pause 用于暂停正在执行的批处理文件,按任意键后继续 3 echo 在控制台显示一段文本 如果显示变量的值需要在变量前后加% 如echo %var% 如果要输出操作系统的名字 就是 echo %os% 4 echo off 可以将命令本身隐藏 如果要连ech

how tomcat works读书笔记 七 日志记录器

大家能够松一口气了,这个组件比較简单,这一节和前面几节想比,也简单的多. Logger接口 Tomcat中的日志记录器都必须实现org.apache.catalina.Logger接口. package org.apache.catalina; import java.beans.PropertyChangeListener; public interface Logger { public static final int FATAL = Integer.MIN_VALUE; public s

How Tomcat Works读书笔记三-------连接器

几个概念 HttpServlet,Servlet Servlet是一个接口,定义了一种网络服务,我们所有的servlet都要实现它(或它的子类) HttpServlet是一个抽象类,它针对的就是http网络服务 当然如果以后再有其他的网络服务,可以再定义一个类,让它实现Servlet即可. HttpServletRequest,ServletRequest 先说ServletRequest接口,它用来传递网络服务的请求,用在Servlet类的service方法. 那么HttpServletReq

how tomcat works 读书笔记 十一 StandWrapper 上

方法调用序列 下图展示了方法调用的协作图: 这个是前面第五章里,我画的图: 我们再回顾一下自从连接器里 connector.getContainer().invoke(request, response); 这句代码运行之后发生的事情; 这是第五章的时序图,放在这一章同样适用... 我们仔细分析一下: 1首先连接器创建请求与响应对象; 2调用这行代码 connector.getContainer().invoke(request, response) (我们一StandContext为顶层容器)

how tomcat works 读书笔记(一)----------一个简单的web服务器

http协议 若是两个人能正常的说话交流,那么他们间必定有一套统一的语言规则<在网络上服务器与客户端能交流也依赖与一套规则,它就是我们说的http规则(超文本传输协议Hypertext transfer protocol). http分两部分,一个是请求(客户端发给服务器),一个是回复(服务器发给客户端). 先看http请求 下面就是一个http请求的例子,其中的各项参数,请查阅相关资料.(http://www.cnblogs.com/yin-jingyu/archive/2011/08/01/

How tomcat works 读书笔记十五 Digester库

Digester库 在前面的几个章节里,我们对tomcat里各个组件的配置完全是使用写硬编码的形式完成的. 如 Context context = new StandardContext(); Loader loader = new WebappLoader(); context.setLoader(loader); 就完成了向context容器里添加WepappLoader的功能. 这么做的问题就在于,一旦我想更改配置就必须得重新加载Bootstrap类. 幸运的是tomcat的设计者使用了一

How tomcat works 读书笔记十五 Digester库 下

在这一节里我们说说ContextConfig这个类. 这个类在很早的时候我们就已经使用了(之前那个叫SimpleContextConfig),但是在之前它干的事情都很简单,就是吧context里的configured变量置为true.在这里我们看看完整版的ContextConfig都干了什么. 在tomcat的实际部署中,StandContext类的实际监听器是org.apache.catalina.startup.ContextConfig的实例. ContextConfig完成加载验证器阀,