很早之前,不知从哪里看的,觉得挺好,记录下来。
原网址:???
=========================================
Jetty Server 和 3大类型的组件相关联:
<1> Connector: 连接器,负责连接客户端发起的 HTTP connections。
<2> Handler: 处理器,接受处理来自HTTP connections 的请求,并对其进行内容相应。
<3> ThreadPool : 线程池,管理和调度多个线程,用来服务于HTTP connections 和 Handler 的运行。
Connector具有众多实现类的原因,主要是由于socket编程模型和不同的协议来决定的。Connector在Jetty中扮演重要 的角色,职责是接收来自客户端的请求,根据HTTP协议解析请求的内容,指派一个线程去处理请求并响应结果。
Handler在Jetty里面对应着一个接口,我们来看看这个接口的核心方 法:
public void handle(String target, HttpServletRequest request, HttpServletResponse response, int dispatch) throws IOException,ServletException;
参数target是指客户端请求的地址,也就是URI;这里我们发现request和response的类型分别是来自Servlet规范里面的 HttpServletRequest和HttpServletResponse接口,那么我们可以得知HttpConnection引用的Request和Response类分别就是这两个接口的实现了。
Handler 的UML 类图:
HandlerWraper 的详细类图:
Jetty正是利用这些种类繁多的Handler来实现其强大的功能的,你可以任意组合、搭配它们来定制各种强大的功能。这么多Handler也就分为三类:
1. 内容输出Handler
该类Handler根据target输出内容。如:ResourceHandler、ServletHandler、DefaultHandler等。 这些类都是直接对Handler接口进行实现。
2. 装饰模式Handler
该类Handler可以选择在交给另外一个Handler对象调用前或后来处理Request和Response。这些类都继承自 HandlerWrapper类,如图2.4中展示的。大家会注意到Server类也是一个装饰模式Handler,其实在Server代理了所有其他的 Handler,是所有Handler的入口。HandlerWrapper中的setHandler方法便是用来设定被代理Handler对象的,这个 方法在以后大家会经常用到。另外装饰器模式还运行将多个Handler串联起来使用。
3.集合类Handler
该类Handler的作用是讲请求分发给其他Handler处理,分发策略由各自实现类决定。常用集合类Handler有 HandlerCollection、HandlerList、ContextHandlerCollection。
Server代表一个Jerry服务器对象,它的作用就好象一个插线板,把Connector、Handler和ThreadPool集成在一起让它们 协同起来工作。
要让Jetty服务器工作起来,我们首先初始化一个Server对象实例,然后给它注册一个或多个Connector对象实例、注册一个 ThreadPool对象、注册多个Handler对象并让这些Handler组合起来。OK,这样一个Jetty服务器便组装完成。
让我们重温一个Jetty的一个处理请求的过程吧,首先Connector收到一个请求,Connector根据HTTP/1.1协议将请求包装成为 Handler所认识的Request和Response对象,然后用Server提供的ThreadPool对象来分配一个线程去执行Handler调 用,注意Server对象算是一个Handler对象,所以从Server开始去交给其他Handler对象处理。
关于ThreadPool,Jetty为我们提供了两个实现版本:org.mortbay.thread.concurrent.ThreadPool 和org.mortbay.thread.QueuedThreadPool。当j2se是1.5以上版本是我们选择ThreadPool的实现。 ThreadPool存在的目的是因为线程的创建是非常昂贵的操作,所以使用Pool技术以便重复使用以创建的线程。
ThreadPool的大致工作方式是:如果存在一个空闲线程,则让它去执行请求处理。如果不存在且没有达到设定的最大线程数,那么就新建一个 Thread去执行请求处理。如果已经达到最大线程数,那么就将工作任务放到队列里面排队,等到有空闲线程时再执行任务。