﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-WOLF--执着-文章分类-Tomcat代码和模式学习</title><link>http://www.blogjava.net/sutao/category/25677.html</link><description>用文字记录学习的体验！</description><language>zh-cn</language><lastBuildDate>Sat, 24 Nov 2007 07:26:22 GMT</lastBuildDate><pubDate>Sat, 24 Nov 2007 07:26:22 GMT</pubDate><ttl>60</ttl><item><title>tomcat6使用nio</title><link>http://www.blogjava.net/sutao/articles/162796.html</link><dc:creator>苏醄</dc:creator><author>苏醄</author><pubDate>Sat, 24 Nov 2007 02:48:00 GMT</pubDate><guid>http://www.blogjava.net/sutao/articles/162796.html</guid><wfw:comment>http://www.blogjava.net/sutao/comments/162796.html</wfw:comment><comments>http://www.blogjava.net/sutao/articles/162796.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sutao/comments/commentRss/162796.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sutao/services/trackbacks/162796.html</trackback:ping><description><![CDATA[<span style="color: #0000ff">很早就听说tomcat6使用nio了，这几天突然想到一个问题，使用nio代替传统的bio，ThreadLocal岂不是会存在冲突？ <br />
　　 <br />
　　 <br />
　　 <br />
　　首先，何谓nio？ <br />
　　 <br />
　　如果读者有socket的编程基础，应该会接触过堵塞socket和非堵塞socket，堵塞socket就是在accept、read、write等IO操作的的时候，如果没有可用符合条件的资源，不马上返回，一直等待直到有资源为止。而非堵塞socket则是在执行select的时候，当没有资源的时候堵塞，当有符合资源的时候，返回一个信号，然后程序就可以执行accept、read、write等操作，这个时候，这些操作是马上完成，并且马上返回。而windows的winsock则有所不同，可以绑定到一个EventHandle里，也可以绑定到一个HWND里，当有资源到达时，发出事件，这时执行的io操作也是马上完成、马上返回的。一般来说，如果使用堵塞socket，通常我们时开一个线程accept socket，当有socket链接的时候，开一个单独的线程处理这个socket；如果使用非堵塞socket，通常是只有一个线程，一开始是select状态，当有信号的时候马上处理，然后继续select状态。 <br />
　　 <br />
　　按照大多数人的说法，堵塞socket比非堵塞socket的性能要好。不过也有小部分人并不是这样认为的，例如Indy项目（Delphi一个比较出色的网络包），它就是使用多线程＋堵塞socket模式的。另外，堵塞socket比非堵塞socket容易理解，符合一般人的思维，编程相对比较容易。 <br />
　　 <br />
　　nio其实也是类似上面的情况。在JDK1.4，sun公司大范围提升Java的性能，其中NIO就是其中一项。Java的IO操作集中在java.io这个包中，是基于流的阻塞API（即BIO，Block IO）。对于大多数应用来说，这样的API使用很方便，然而，一些对性能要求较高的应用，尤其是服务端应用，往往需要一个更为有效的方式来处理IO。从JDK 1.4起，NIO API作为一个基于缓冲区，并能提供非阻塞O操作的API（即NIO，non-blocking IO）被引入。 <br />
　　 <br />
　　BIO与NIO一个比较重要的不同，是我们使用BIO的时候往往会引入多线程，每个连接一个单独的线程；而NIO则是使用单线程或者只使用少量的多线程，每个连接共用一个线程。 <br />
　　 <br />
　　 <br />
　　 <br />
　　这个时候，问题就出来了：我们非常多的java应用是使用ThreadLocal的，例如JSF的FaceContext、Hibernate的session管理、Struts2的Context的管理等等，几乎所有框架都或多或少地应用ThreadLocal。如果存在冲突，那岂不惊天动地？ <br />
　　 <br />
　　后来终于在Tomcat6的文档（http://tomcat.apache.org/tomcat-6.0-doc/aio.html）找到答案。根据上面说明，应该Tomcat6应用nio只是用在处理发送、接收信息的时候用到，也就是说，tomcat6还是传统的多线程Servlet，我画了下面两个图来列出区别： <br />
　　 <br />
　　 <br />
　　 <br />
　　tomcat5：客户端连接到达 -&gt; 传统的SeverSocket.accept接收连接 -&gt; 从线程池取出一个线程 -&gt; 在该线程读取文本并且解析HTTP协议 -&gt; 在该线程生成ServletRequest、ServletResponse，取出请求的Servlet -&gt; 在该线程执行这个Servlet -&gt; 在该线程把ServletResponse的内容发送到客户端连接 -&gt; 关闭连接。 <br />
　　 <br />
　　我以前理解的使用nio后的tomcat6：客户端连接到达 -&gt; nio接收连接 -&gt; nio使用轮询方式读取文本并且解析HTTP协议（单线程） -&gt; 生成ServletRequest、ServletResponse，取出请求的Servlet -&gt; 直接在本线程执行这个Servlet -&gt; 把ServletResponse的内容发送到客户端连接 -&gt; 关闭连接。 <br />
　　 <br />
　　实际的tomcat6：客户端连接到达 -&gt; nio接收连接 -&gt; nio使用轮询方式读取文本并且解析HTTP协议（单线程） -&gt; 生成ServletRequest、ServletResponse，取出请求的Servlet -&gt; 从线程池取出线程，并在该线程执行这个Servlet -&gt; 把ServletResponse的内容发送到客户端连接 -&gt; 关闭连接。 <br />
　　 <br />
　　 <br />
　　 <br />
　　从上图可以看出，BIO与NIO的不同，也导致进入客户端处理线程的时刻有所不同：tomcat5在接受连接后马上进入客户端线程，在客户端线程里解析HTTP协议，而tomcat6则是解析完HTTP协议后才进入多线程，另外，tomcat6也比5早脱离客户端线程的环境。 <br />
　　 <br />
　　实际的tomcat6与我之前猜想的差别主要集中在如何处理servlet的问题上。实际上即使抛开ThreadLocal的问题，我之前理解tomcat6只使用一个线程处理的想法其实是行不同的。大家都有经验：servlet是基于BIO的，执行期间会存在堵塞的，例如读取文件、数据库操作等等。tomcat6使用了nio，但不可能要求servlet里面要使用nio，而一旦存在堵塞，效率自然会锐降。 <br />
　　 <br />
　　 <br />
　　 <br />
　　 <br />
　　所以，最终的结论当然是tomcat6的servlet里面，ThreadLocal照样可以使用，不存在冲突。 <br />
　　 </span>
<img src ="http://www.blogjava.net/sutao/aggbug/162796.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sutao/" target="_blank">苏醄</a> 2007-11-24 10:48 <a href="http://www.blogjava.net/sutao/articles/162796.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>TOMCAT框架分析(消息处理)</title><link>http://www.blogjava.net/sutao/articles/143620.html</link><dc:creator>苏醄</dc:creator><author>苏醄</author><pubDate>Sat, 08 Sep 2007 08:38:00 GMT</pubDate><guid>http://www.blogjava.net/sutao/articles/143620.html</guid><wfw:comment>http://www.blogjava.net/sutao/comments/143620.html</wfw:comment><comments>http://www.blogjava.net/sutao/articles/143620.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sutao/comments/commentRss/143620.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sutao/services/trackbacks/143620.html</trackback:ping><description><![CDATA[<span style="font-family: 宋体;">0：前言</span>
<p style="text-indent: 21pt;"><span style="font-family: 宋体;">我们知道了<strong style="color: black; background-color: #ffff66;">tomcat</strong>的整体框架了， 也明白了里面都有些什么组件， 以及各个组件是干什么用的了。</span></p>
<p style="text-indent: 21pt;"><span style="font-family: 宋体;">http://www.csdn.net/Develop/read_article.asp?id=27225</span></p>
<p style="text-indent: 21pt;"><span style="font-family: 宋体;">我想，接下来我们应该去了解一下 <strong style="color: black; background-color: #ffff66;">tomcat</strong> 是如何处理jsp和servlet请求的。</span></p>
<p><span style="font-family: 宋体;">1. &nbsp;我们以一个具体的例子，来跟踪</span><strong style="color: black; background-color: #ffff66;">TOMCAT</strong><span style="font-family: 宋体;">，</span><span style="font-family: 宋体;">看看它是如何把</span>Request<span style="font-family: 宋体;">一层一层地递交给下一个容器，</span><span style="font-family: 宋体;">并最后交给</span>Wrapper<span style="font-family: 宋体;">来处理的。</span></p>
<p style="margin-left: 21pt;"><span style="font-family: 宋体;">以</span><u><span style="color: blue;">http://localhost:8080/web/login.jsp</span></u><span style="font-family: 宋体;">为例子</span></p>
<p style="margin-left: 21pt;"><span style="font-family: 宋体;">（以下例子，</span><span style="font-family: 宋体;">都是以</span><strong style="color: black; background-color: #ffff66;">tomcat</strong>4 <span style="font-family: 宋体;"><strong style="color: black; background-color: #a0ffff;">源码</strong>为参考）</span></p>
<p style="margin-left: 21pt;"><span style="font-family: 宋体;">这篇心得主要分为3个部分： 前期， 中期， 和末期。</span></p>
<p style="margin-left: 21pt;">&nbsp;<span style="font-family: 宋体;">前期：讲解了在浏览器里面输入一个URL，是怎么被<strong style="color: black; background-color: #ffff66;">tomcat</strong>抓住的。</span></p>
<p style="margin-left: 21pt;"><span style="font-family: 宋体;">中期：讲解了被<strong style="color: black; background-color: #ffff66;">tomcat</strong>抓住后，又是怎么在各个容器里面穿梭， 最后到达最后的处理地点。</span></p>
<p style="margin-left: 21pt;"><span style="font-family: 宋体;">末期：讲解到达最后的处理地点后，又是怎么具体处理的。</span></p>
<p style="margin-left: 21pt;">2<span style="font-family: 宋体;">、</span>&nbsp;<span style="font-family: 宋体;">前期 Request的born.</span></p>
<p style="margin-left: 21pt; text-indent: -21pt;"><span style="font-family: 宋体;">&nbsp;&nbsp;&nbsp; 在这里我先简单讲一下request这个东西。</span></p>
<p style="margin-left: 21pt; text-indent: -21pt;"><span style="font-family: 宋体;">&nbsp;&nbsp;&nbsp;&nbsp; 我们先看着这个URL：</span><u><span style="color: blue;">http://localhost:8080/web/login.jsp</span></u><span style="color: black; font-family: 宋体;">&nbsp;它是动用了8080端口来进行socket通讯的。</span></p>
<p style="margin-left: 21pt; text-indent: -21pt;"><span style="color: black; font-family: 宋体;">&nbsp;&nbsp;&nbsp;&nbsp; 我们知道, 通过 </span></p>
<p style="margin-left: 21pt; text-indent: -21pt;"><span style="color: black; font-family: 宋体;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InputStream in = socket.getInputStream() 和</span></p>
<p style="margin-left: 21pt; text-indent: -21pt;"><span style="color: black; font-family: 宋体;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OutputStream out = socket.getOutputStream() </span></p>
<p style="text-indent: -1.05pt;"><span style="color: black; font-family: 宋体;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;就可以实现消息的来来往往了。</span></p>
<p style="margin-left: 21pt; text-indent: -21pt;"><span style="color: black; font-family: 宋体;">&nbsp;&nbsp;&nbsp;&nbsp; 但是如果把Stream给应用层看，显然操作起来不方便。 </span></p>
<p style="margin-left: 21pt; text-indent: -21pt;"><span style="color: black; font-family: 宋体;">&nbsp;&nbsp;&nbsp;&nbsp; 所以，在<strong style="color: black; background-color: #ffff66;">tomcat</strong> 的Connector里面， socket被封装成了Request和Response这两个对象。</span></p>
<p style="margin-left: 21pt; text-indent: -21pt;"><span style="color: black; font-family: 宋体;">&nbsp;&nbsp;&nbsp;&nbsp; 我们可以简单地把Request看成管发到服务器来的数据，把Response看成想发出服务器的数据。</span></p>
<p style="margin-left: 21pt; text-indent: -21pt;"><span style="color: black; font-family: 宋体;">&nbsp;&nbsp;&nbsp; &nbsp;</span></p>
<p style="margin-left: 21pt; text-indent: -21pt;"><span style="color: black; font-family: 宋体;">&nbsp;&nbsp;&nbsp;&nbsp; 但是这样又有其他问题了啊？ Request这个对象是把socket封装起来了， 但是他提供的又东西太多了。</span></p>
<p style="margin-left: 21pt; text-indent: -21pt;"><span style="color: black; font-family: 宋体;">&nbsp;&nbsp;&nbsp;&nbsp; 诸如Request.getAuthorization(), Request.getSocket()。&nbsp;像Authorization
这种东西开发人员拿来基本上用不太着，而像socket这种东西，暴露给开发人员又有潜在的危险。 而且啊， 在Servlet
Specification里面标准的通信类是ServletRequest和HttpServletRequest，而非这个Request类。
So, So, So. <strong style="color: black; background-color: #ffff66;">Tomcat</strong>必须得捣持捣持Request才行。 最后<strong style="color: black; background-color: #ffff66;">tomcat</strong>选择了使用捣持模式（应该叫适配器模式）来解决这个问题。它把org.apache.catalina.Request 捣持成了 org.apache.coyote.<strong style="color: black; background-color: #ffff66;">tomcat</strong>4.CoyoteRequest。 而CoyoteRequest又实现了ServletRequest和HttpServletRequest 这两种接口。 这样就提供给开发人员需要且刚刚需要的方法了。</span></p>
<p style="margin-left: 21pt; text-indent: -21pt;"><span style="color: black; font-family: 宋体;">&nbsp;</span></p>
<p style="margin-left: 21pt; text-indent: -21pt;">&nbsp;&nbsp;&nbsp; ok, <span style="font-family: 宋体;">让</span><span style="font-family: 宋体;">我们在 <strong style="color: black; background-color: #ffff66;">tomcat</strong>的顶层容器 - </span>StandardEngin <span style="font-family: 宋体;">的invoke()方法这里设置一个断点， 然后访问</span></p>
<p style="margin-left: 21pt; text-indent: -21pt;"><span style="font-family: 宋体;">&nbsp;&nbsp;&nbsp; </span><u><span style="color: blue;">http://localhost:8080/web/login.jsp</span></u><span style="color: black; font-family: 宋体;">， 我们来看看在前期都会路过哪些地方：</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-family: 宋体;">1. </span>run(): 536, java.lang.Thread, Thread.java</p>
<p><span style="font-family: 宋体;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; CurrentThread</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.&nbsp;run():666, org.apache.<strong style="color: black; background-color: #ffff66;">tomcat</strong>.util.threads.ThreadPool$ControlRunnable, ThreadPool.java</p>
<p>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;ThreadPool</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.&nbsp;runIt():589, org.apache.<strong style="color: black; background-color: #ffff66;">tomcat</strong>.util.net.TcpWorkerThread, PoolTcpEndpoint.java</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;ThreadWorker</p>
<p style="margin-left: 42pt; text-indent: -20.25pt;">4.<span style="font-family: '','',Times New Roman,'',''; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>processConnection(): &nbsp;549</p>
<p style="margin-left: 21.75pt; text-indent: 20.25pt;">org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler, Http11Protocol.java</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; http protocol parser</p>
<p>&nbsp; &nbsp;&nbsp; &nbsp;5.&nbsp;Process(): 781, org.apache.coyote.http11.Http11Processor, Http11Processor.java</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; http request processor</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6. service(): 193, org.apache.coyote.<strong style="color: black; background-color: #ffff66;">tomcat</strong>4.CoyoteAdapter,CoyoteAdapter.java</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;adapter</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7. invoke(): 995, org.apache.catalina.core.ContainerBase, ContainerBase.java</p>
<p style="text-indent: 21pt;">&nbsp;&nbsp; StandardEngin</p>
<p><span style="font-family: 宋体;">&nbsp;&nbsp;&nbsp; 1. 主线程</span></p>
<p><span style="font-family: 宋体;">&nbsp;&nbsp;&nbsp; 2. 启动线程池.</span></p>
<p><span style="font-family: 宋体;">&nbsp;&nbsp;&nbsp; 3. 调出线程池里面空闲的工作线程。</span></p>
<p><span style="font-family: 宋体;">&nbsp;&nbsp;&nbsp; 4. 把8080端口传过来由httpd协议封装的数据，解析成Request和Response对象。</span></p>
<p><span style="font-family: 宋体;">&nbsp;&nbsp;&nbsp; 5. 使用</span>Http11Processor<span style="font-family: 宋体;">来处理request</span></p>
<p><span style="font-family: 宋体;">&nbsp;&nbsp;&nbsp; 6. 在</span>Http11Processor<span style="font-family: 宋体;">里面， 又会call </span>CoyoteAdapter<span style="font-family: 宋体;">来进行适配处理，把Request适配成实现了ServletRequest和HttpServletRequest接口的</span>CoyoteRequest.</p>
<p style="text-indent: 21pt;">7<span style="font-family: 宋体;">. 到了这里，前期的去毛拔皮工作就基本上搞定，可以交给</span>StandardEngin <span style="font-family: 宋体;">做核心的处理工作了。</span></p>
<p><span style="font-family: 宋体;">3. 中期。 在各个容器间的穿梭。</span></p>
<p><span style="font-family: 宋体;">&nbsp;&nbsp;&nbsp; Request在各个容器里面的穿梭大致是这样一种方式：</span></p>
<p><span style="font-family: 宋体;">&nbsp;&nbsp;&nbsp; 每个容器里面都有一个管道（pipline）， 专门用来传送Request用的。</span></p>
<p><span style="font-family: 宋体;">&nbsp;&nbsp;&nbsp; 管道里面又有好几个阀门（valve）， 专门用来过滤Request用的。</span></p>
<p><span style="font-family: 宋体;">&nbsp;&nbsp;&nbsp; 在管道的低部通常都会放上一个默认的阀们。 这个阀们至少会做一件事情，就是把Request交给子容器。</span></p>
<p><span style="font-family: 宋体;">&nbsp;&nbsp;&nbsp; 让我们来想象一下：</span></p>
<p><span style="font-family: 宋体;">&nbsp;&nbsp;&nbsp;&nbsp; 当一个Request进入一个容器后， 它就在管道里面流动，波罗~ 波罗~ 波罗~ 地穿过各个阀门。在流到最后一个阀门的时候，吧唧~ 那个该死的阀门就把它扔给了子容器。 然后又开始 波罗~ 波罗~ 波罗~ ... 吧唧~....&nbsp;波罗~&nbsp;波罗~ 波罗~ ....吧唧~.... </span></p>
<p><span style="font-family: 宋体;">&nbsp;&nbsp;&nbsp; 就是通过这种方式， Request 走完了所有的容器。（ 感觉有点像消化系统，最后一个地方有点像那里~&nbsp;）</span></p>
<span style="font-family: 宋体;">&nbsp;&nbsp;&nbsp; OK， 让我们具体看看都有些什么容器， 各个容器里面又都有些什么阀门，这些阀们都对我们的Request做了些什么吧：<br />
</span>
<p style="text-indent: 21pt;">3.1 StandardEngin <span style="font-family: 宋体;">的pipeline里面放的是：</span>StandardEnginValve</p>
<p style="text-indent: 21pt;"><span style="font-family: 宋体;">在这里，</span>VALVE<span style="font-family: 宋体;">做了三件事：</span></p>
<p style="margin-left: 39pt; text-indent: -18pt;">1.&nbsp;&nbsp; <span style="font-family: 宋体;">验证传递过来的</span>request<span style="font-family: 宋体;">是不是</span>httpservletRequest.</p>
<p style="margin-left: 39pt; text-indent: -18pt;">2&nbsp;&nbsp;&nbsp; <span style="font-family: 宋体;">验证传递过来的</span> request <span style="font-family: 宋体;">是否携带了</span>host header<span style="font-family: 宋体;">信息</span>.</p>
<p style="margin-left: 39pt; text-indent: -18pt;">3&nbsp;&nbsp;&nbsp; <span style="font-family: 宋体;">选择相应的</span>host<span style="font-family: 宋体;">去处理它。（一般我们都只有一个host:</span>localhost<span style="font-family: 宋体;">，也就是</span>127.0.0.1<span style="font-family: 宋体;">）。</span></p>
<p style="text-indent: 21.3pt;"><span style="font-family: 宋体;">到了这个地方，</span><span style="font-family: 宋体;">我们的</span>request<span style="font-family: 宋体;">就已经完成了在</span>Engin<span style="font-family: 宋体;">这个部分的历史使命，</span><span style="font-family: 宋体;">通向前途未卜的下一站：</span> host<span style="font-family: 宋体;">了。</span></p>
<p style="margin-left: 21pt;">3.2 StandardHost <span style="font-family: 宋体;">的pipline里面放的是：</span> StandardHostValve</p>
<p style="margin-left: 39pt; text-indent: -18pt;">1.&nbsp;&nbsp; <span style="font-family: 宋体;">验证传递过来的</span>request<span style="font-family: 宋体;">是不是</span>httpservletRequest.</p>
<p style="margin-left: 39pt; text-indent: -18pt;">2.&nbsp;&nbsp; <span style="font-family: 宋体;">根据</span>Request<span style="font-family: 宋体;">来确定哪个</span>Context<span style="font-family: 宋体;">来处理。</span></p>
<p style="margin-left: 39pt;">Context<span style="font-family: 宋体;">其实就是</span>webapp<span style="font-family: 宋体;">，</span><span style="font-family: 宋体;">比如</span><u><span style="color: blue;">http://localhost:8080/web/login.jsp</span></u></p>
<p style="margin-left: 39pt;"><span style="font-family: 宋体;">这里</span>web<span style="font-family: 宋体;">就是</span>Context<span style="font-family: 宋体;">罗！</span></p>
<p style="margin-left: 39pt; text-indent: -18pt;">3.&nbsp;&nbsp; <span style="font-family: 宋体;">既然确定了是哪个</span>Context<span style="font-family: 宋体;">了，那么就应该把那个</span>Context<span style="font-family: 宋体;">的</span>classloader<span style="font-family: 宋体;">付给当前线程了。</span></p>
<p style="margin-left: 39pt; text-indent: -18pt;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thread.currentThread().setContextClassLoader(context.getLoader().getClassLoader());</p>
<p style="margin-left: 39pt; text-indent: -18pt;">&nbsp;&nbsp; <span style="font-family: 宋体;">这样</span>request<span style="font-family: 宋体;">就只看得见指定的</span>context<span style="font-family: 宋体;">下面的</span>classes<span style="font-family: 宋体;">啊，</span> jar<span style="font-family: 宋体;">啊这些，</span><span style="font-family: 宋体;">而看不见</span>tomcat<span style="font-family: 宋体;">本身的类，</span><span style="font-family: 宋体;">什么</span>Engin<span style="font-family: 宋体;">啊，</span> Valve<span style="font-family: 宋体;">啊。</span><span style="font-family: 宋体;">不然还得了啊！</span></p>
<p style="margin-left: 39pt; text-indent: -18pt;"><span style="font-family: 宋体;">4. 既然request到了这里了，看来用户是准备访问web这个web app了，咋们得更新一下这个用户的session不是！ Ok , 就由manager更新一下用户的session信息</span></p>
<p style="margin-left: 39pt; text-indent: -18pt;"><span style="font-family: 宋体;">5. 交给具体的Context 容器去继续处理Request.</span></p>
<p style="margin-left: 39pt; text-indent: -18pt;"><span style="font-family: 宋体;">6. Context处理完毕了，把</span>classloader<span style="font-family: 宋体;">还回来。</span></p>
<p style="margin-left: 21pt;">3.3 StandardContext <span style="font-family: 宋体;">的pipline里面放的是：</span> StandardContextValve</p>
<p style="margin-left: 39pt; text-indent: -18pt;">1.&nbsp;&nbsp; <span style="font-family: 宋体;">验证传递过来的</span>request<span style="font-family: 宋体;">是不是</span>httpservletRequest.</p>
<p style="margin-left: 39pt; text-indent: -18pt;">2.&nbsp;&nbsp; <span style="font-family: 宋体;">如果</span>request<span style="font-family: 宋体;">意图不轨，想要访问</span>/meta-inf, /web-inf<span style="font-family: 宋体;">这些目录下的东西，呵呵，没有用D!</span></p>
<p style="margin-left: 39pt; text-indent: -18pt;">3.&nbsp;&nbsp; <span style="font-family: 宋体;">这个时候就会根据</span>Request<span style="font-family: 宋体;">到底是</span>Servlet<span style="font-family: 宋体;">，</span><span style="font-family: 宋体;">还是</span>jsp<span style="font-family: 宋体;">，</span><span style="font-family: 宋体;">还是静态资源来决定到底用哪种</span>Wrapper<span style="font-family: 宋体;">来处理这个</span>Reqeust<span style="font-family: 宋体;">了。</span></p>
<p style="margin-left: 39pt; text-indent: -18pt;">4.&nbsp;&nbsp; <span style="font-family: 宋体;">一旦决定了到底用哪种</span>Wrapper<span style="font-family: 宋体;">，</span>OK<span style="font-family: 宋体;">，交给那个</span>Wrapper<span style="font-family: 宋体;">处理。</span></p>
<p style="margin-left: 39pt; text-indent: -39pt;"><span style="font-family: 宋体;">4. 末期。 不同的需求是怎么处理的.</span></p>
<p style="margin-left: 39pt; text-indent: -18pt;"><span style="font-family: 宋体;">StandardWrapper</span></p>
<p style="margin-left: 39pt; text-indent: -18pt;"><span style="font-family: 宋体;">之前对Wrapper没有做过讲解，其实它是这样一种东西。</span></p>
<p style="margin-left: 39pt; text-indent: -18pt;"><span style="font-family: 宋体;">我们在处理Request的时候，可以分成3种。</span></p>
<p style="margin-left: 39pt; text-indent: -18pt;"><span style="font-family: 宋体;">处理静态的： org.apache.catalina.servlets.DefaultServlet&nbsp;&nbsp; </span></p>
<p style="margin-left: 39pt; text-indent: -18pt;"><span style="font-family: 宋体;">处理jsp的：org.apache.jasper.servlet.JspServlet </span></p>
<p style="margin-left: 39pt; text-indent: -18pt;"><span style="font-family: 宋体;">处理servlet的：org.apache.catalina.servlets.InvokerServlet</span></p>
<p style="margin-left: 39pt; text-indent: -18pt;"><span style="font-family: 宋体;">不同的request就用这3种不同的servlet去处理。</span></p>
<p style="margin-left: 39pt; text-indent: -18pt;"><span style="font-family: 宋体;">Wrapper就是对它们的一种简单的封装，有了Wrapper后，我们就可以轻松地拦截每次的Request。也可以容易地调用servlet的init()和destroy()方法， 便于管理嘛！</span></p>
<p style="margin-left: 39pt; text-indent: -18pt;"><span style="font-family: 宋体;">具体情况是这么滴：</span></p>
<p style="margin-left: 39pt; text-indent: -18pt;"><span style="font-family: 宋体;">&nbsp;&nbsp; 如果request是找jsp文件，StandardWrapper里面就会封装一个org.apache.jasper.servlet.JspServlet去处理它。</span></p>
<p style="margin-left: 39pt; text-indent: -18pt;"><span style="font-family: 宋体;">&nbsp;&nbsp; 如果request是找 静态资源 ，StandardWrapper里面就会封装一个org.apache.jasper.servlet.DefaultServlet&nbsp;去处理它。</span></p>
<p style="margin-left: 39pt; text-indent: -18pt;"><span style="font-family: 宋体;">&nbsp;&nbsp; 如果request是找servlet ，StandardWrapper里面就会封装一个org.apache.jasper.servlet.InvokerServlet 去处理它。</span></p>
<p style="margin-left: 39pt; text-indent: -18pt;"><span style="font-family: 宋体;">StandardWrapper同样也是容器，既然是容器， 那么里面一定留了一个管道给request去穿，管道低部肯定也有一个阀门(注1)，用来做最后一道拦截工作.</span></p>
<p style="margin-left: 39pt; text-indent: -18pt;"><span style="font-family: 宋体;">在这最底部的阀门里，其实就主要做了两件事:</span></p>
<p style="margin-left: 39pt; text-indent: -18pt;"><span style="font-family: 宋体;">&nbsp;&nbsp; 一是启动过滤器，让request在N个过滤器里面筛一通，如果OK！ 那就PASS。 否则就跳到其他地方去了。</span></p>
<p style="margin-left: 39pt; text-indent: -18pt;"><span style="font-family: 宋体;">&nbsp;&nbsp; 二是servlet.service((HttpServletRequest) request,(HttpServletResponse) response); 这个方法.</span></p>
<p style="margin-left: 39pt; text-indent: -18pt;"><span style="font-family: 宋体;">&nbsp;&nbsp;&nbsp;&nbsp; 如果是 JspServlet， 那么先把jsp文件编译成servlet_xxx, 再invoke servlet_xxx的servie()方法。</span></p>
<p style="margin-left: 39pt; text-indent: -18pt;"><span style="font-family: 宋体;">&nbsp;&nbsp;&nbsp;&nbsp; 如果是 DefaultServlet， 就直接找到静态资源，取出内容， 发送出去。</span></p>
<p style="margin-left: 39pt; text-indent: -18pt;"><span style="font-family: 宋体;">&nbsp;&nbsp;&nbsp;&nbsp; 如果是 InvokerServlet， 就调用那个具体的servlet的service()方法。</span></p>
<p style="margin-left: 39pt; text-indent: -18pt;"><span style="font-family: 宋体;">&nbsp;&nbsp; ok! 完毕。</span></p>
<p style="margin-left: 39pt; text-indent: -18pt;"><span style="font-family: 宋体;">注1:
StandardWrapper 里面的阀门是最后一道关口了。 如果这个阀门欲意把request交给StandardWrapper
的子容器处理。 对不起， 在设计考虑的时候， Wrapper就被考虑成最末的一个容器， 压根儿就不会给Wrapper添加子容器的机会！
如果硬是要调用addChild(), 立马抛出IllegalArgumentException！</span></p>
<p style="margin-left: 39pt; text-indent: -18pt;"><span style="font-family: 宋体;">参考：</span></p>
<p style="margin-left: 39pt; text-indent: -18pt;"><font color="#0a0011">&nbsp;<span style="font-family: 宋体;">&nbsp;&nbsp;&nbsp; </span></font><font color="#0a0011">&lt;</font><a href="http://jakarta.apache.org/tomcat/"><font color="#0a0011">http://jakarta.apache.org/tomcat/</font></a><font color="#0a0011">&gt;<br />
&nbsp;&nbsp;&nbsp;&lt;</font><a href="http://www.onjava.com/pub/a/onjava/2003/05/14/java_webserver.html"><font color="#0a0011">http://www.onjava.com/pub/a/onjava/2003/05/14/java_webserver.html</font></a><font color="#0a0011">&gt;</font></p>
<p style="margin-left: 39pt; text-indent: -18pt;"><span style="color: #333333; font-family: Arial;"><font color="#0a0011">&nbsp;</font></span></p>
<br />
<img src ="http://www.blogjava.net/sutao/aggbug/143620.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sutao/" target="_blank">苏醄</a> 2007-09-08 16:38 <a href="http://www.blogjava.net/sutao/articles/143620.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Tomcat的源码分析</title><link>http://www.blogjava.net/sutao/articles/143617.html</link><dc:creator>苏醄</dc:creator><author>苏醄</author><pubDate>Sat, 08 Sep 2007 08:08:00 GMT</pubDate><guid>http://www.blogjava.net/sutao/articles/143617.html</guid><wfw:comment>http://www.blogjava.net/sutao/comments/143617.html</wfw:comment><comments>http://www.blogjava.net/sutao/articles/143617.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/sutao/comments/commentRss/143617.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/sutao/services/trackbacks/143617.html</trackback:ping><description><![CDATA[<table style="width: 100%;" border="0" cellpadding="0" cellspacing="0" width="100%">
    <tbody>
        <tr>
            <td style="padding: 0cm;">
            <br />
            </td>
        </tr>
    </tbody>
</table>
<p style="text-align: left;" align="left"><strong><span style="font-size: 18pt; font-family: 宋体;">从<span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span>中得到更多－<span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span>的源码<span style="background: #99ff99 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">分析</span></span></strong></p>
<p style="text-align: left;" align="left"><strong><span style="font-size: 13.5pt; font-family: 宋体;">赵晨希</span></strong></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">&lt;<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#122;&#104;&#97;&#111;&#99;&#104;&#101;&#110;&#120;&#105;&#64;&#118;&#105;&#112;&#46;&#115;&#105;&#110;&#97;&#46;&#99;&#111;&#109;">zhaochenxi@vip.sina.com</a>&gt;</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">本文的作者通过对<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">TomCat</span></strong>源代码的研究，向读者描述了在<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">tomcat</span></strong>3.3和<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">TomCat</span></strong>4.0中在设计方面使用的不同设计理念和模式，希望对广大开发者在设计自己的系统时有所帮助。</span></p>
<p style="text-align: left;" align="left"><strong><span style="font-size: 18pt; font-family: 宋体;">关于<span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span>的基本情况</span></strong></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">众所周知<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>是一个免费的开放源码的Serlvet容器，它是Apache基金会的Jakarta项目中的一个核心项目，也是sun公司官方推荐的servlet和jsp容器，同时它还获得过多种荣誉。servlet和jsp的最新规范都可以在<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">tomcat</span></strong>的新版本中得到实现。<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>具有轻量级和灵活嵌入到应用系统中的优点，所以得到了广泛的应用。在<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>的发展中，Sun在1999年六月宣布参与Jakarta项目的<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong> servlet容器和Jsp引擎的开发，使得<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>在3.x和4.x版之间系统设计上发生了比较大的变化。<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>的其他信息我就不多说了。有兴趣的朋友可以访问http://jakarta.apache.org/ 的官方网站得到更多的信息。</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">因为工作的原因，我改写了<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>的一些代码，所以我粗略的研究了一下<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>3.3和<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>4.0的源码，深深地被这个开放软件的设计和实现吸引，感觉到这个软件中有许多值得我们学习和借鉴的地方。我把自己的理解介绍给大家算是抛砖引玉，不足和偏差还望大家批评指正。下面就来让我们看看从
<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>那里我们可以得到什么。</span></p>
<p style="text-align: left;" align="left"><strong><span style="font-size: 18pt; font-family: 宋体;">从<span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span>中学习设计模式</span></strong></p>
<p style="text-align: left;" align="left"><strong><span style="background: #ffff66 none repeat scroll 0% 50%; font-size: 12pt; font-family: 宋体; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong><span style="font-size: 12pt; font-family: 宋体;">的设计和实现处处体现着设计模式的思想，它的基本流程是首先通过解析xml格式的配置文件，获得系统的配置和应用信息，然后加载定制的组件模块提供各种系统服务。系统的各部分功能都是通过可以配置的组件模块来实现的。<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>实现中像Observer，Facade，Adapter， Singleton等多种设计模型在<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>的源码中随处可见，为我们提供了一个很好的学习设计模式的平台。我主要介绍一下<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>中程序流程控制所采用的设计模式，这是一个程序运行的框架。前面提到由于Sun公司的参与，<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>虽然基本的流程没有变化，但是<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>3.3和 <strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>4.0版本之间在概念上还是有很大地不同的。<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>3.3整体上是模块化的设计，而<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>4.0可以看作是采用面向组件技术进行设计的。组件是比模块更高级的一个层次。我们可以通过比较它们之间的不同来了解实现一个服务器软件可以采用的设计模式和实现方式。</span></p>
<p style="text-align: left;" align="left"><strong><span style="background: #ffff66 none repeat scroll 0% 50%; font-size: 13.5pt; font-family: 宋体; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong><strong><span style="font-size: 13.5pt; font-family: 宋体;">3.3</span></strong><strong><span style="font-size: 13.5pt; font-family: 宋体;">的基本<span style="background: #a0ffff none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">结构</span>设计</span></strong></p>
<p style="text-align: left;" align="left"><strong><span style="background: #ffff66 none repeat scroll 0% 50%; font-size: 12pt; font-family: 宋体; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong><span style="font-size: 12pt; font-family: 宋体;">3.3</span><span style="font-size: 12pt; font-family: 宋体;">采用的是一种模块化的链状的控制<strong><span style="background: #a0ffff none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">结构</span></strong>，它的主要设计模式有：</span></p>
<p style="text-align: left;" align="left"><strong><span style="font-size: 12pt; font-family: 宋体;">Chain of responsibility</span></strong><strong><span style="font-size: 12pt; font-family: 宋体;">（责任链）</span></strong></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">作为一个基于请求响应模式的服务器，在<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>3.3中采用一种链状处理的控制模式。请求在链上的各个环节上传递，在任一环节上可以存在若干个"监听器"处理它。这样做的目的是避免请求的发送者和接受者之间的直接耦合，从而可以为其他的对象提供了参与处理请求的机会。采用这个方式不但可以通过"监听器 "实现系统功能，而且可以通过添加新的"监听器"对象实现系统功能的扩展。</span></p>
<p style="text-align: left;" align="left"><strong><span style="font-size: 12pt; font-family: 宋体;">Interceptor</span></strong><strong><span style="font-size: 12pt; font-family: 宋体;">（监听器）</span></strong></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">"</span><span style="font-size: 12pt; font-family: 宋体;">监听器"是一个过去使用的名称，它可以看作 "模块(module)"的同义词。它是<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>功能模块构建和扩展的方式。<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>3.3的大部分功能都是通过"监听器"实现的。在 <strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>中提供了一种简单的钩子（Hook）机制，监听器对钩子中感兴趣的事件进行注册，事件发生后通过钩子唤醒已注册的"监听器"对象，"监听器" 对象对<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>内核事件进行处理。这些模块都是围绕着"责任链"和"策略"的模式进行设计。通过"监听器"你可以监听各种特殊事件，进而控制处理请求的各个步骤---解析，认证，授权，会话，响应提交，缓冲区提交等等。</span></p>
<p style="text-align: left;" align="left"><strong><span style="font-size: 12pt; font-family: 宋体;">Strategy</span></strong><strong><span style="font-size: 12pt; font-family: 宋体;">（策略）</span></strong></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">所谓策略是指"定义一组规则，按照规则进行对象封装，使得他们只在规则内部进行交互"。通过策略模式使得<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>作为一个开源项目在开放环境下的开发和演变变得更轻松。通过这种模式把复杂的算法分成模块然后不同的开发组提供各自的实现。从而实现调用模块的代码和模块的具体实现代码的分别开发。这样可以使我们专注于问题的重点，并且减少问题之间的依赖性。在<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>中大量采用了策略的设计模式，通过这种方式每一种服务都提供了多种的实现（例如<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>中有2－3种认证模块），在代码完成后可以从稳定性和性能表现的考虑选择更好的实现。策略模式对开放式环境下的软件开发非常有用。</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">我们通过简化的类图(见图一)和时序图(见图二)，描述一下<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>3.3的程序流程控制如何通过监听器和责任链实现。</span></p>
<p style="text-align: left;" align="left"><strong><span style="font-size: 12pt; font-family: 宋体;">图?1.?简化的类图</span></strong></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;"><!--[if gte vml 1]>
<![endif]--></span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">关于类图的简单说明：</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">BaseInterceptor</span><span style="font-size: 12pt; font-family: 宋体;">：</span></p>
<p style="margin-left: 36pt; text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">是所有监听器的基类，描述了基本的模块功能和对各种事件的缺省处理。</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">ContextManage</span><span style="font-size: 12pt; font-family: 宋体;">：</span></p>
<p style="margin-left: 36pt; text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">系统的核心控制对象，进行请求处理和系统配置。它维护了全局的属性、web应用的内容和全局模块等多种信息，责任链的钩子实现也在其中。</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">PoolTcpConnector</span><span style="font-size: 12pt; font-family: 宋体;">：</span></p>
<p style="margin-left: 36pt; text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">一个处理TCP连接的连接器对象，从BaseIntercepor派生。它包括一个具体处理socket连接的PoolTcpEndPoint类对象。</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">PoolTcpEndPoint</span><span style="font-size: 12pt; font-family: 宋体;">：</span></p>
<p style="margin-left: 36pt; text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">处理实际的tcp连接。它有一个连接池对象ThreadPool和运行在独立线程中的应用逻辑类TcpWorkThread。</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">TcpWorkThead</span><span style="font-size: 12pt; font-family: 宋体;">：</span></p>
<p style="margin-left: 36pt; text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">处理socket连接事务，调用接口TcpConnectionHandler中的请求处理方法。</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">Http10Interceptor</span><span style="font-size: 12pt; font-family: 宋体;">：</span></p>
<p style="margin-left: 36pt; text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">从PoolTcpConnector派生，实现了TcpConnectionHandler接口，是一个真正的监听器对象。它按照Http1.0的协议标准对tcp连接进行处理，调用核心对象ContextManage的服务方法。</span></p>
<p style="text-align: left;" align="left"><strong><span style="font-size: 12pt; font-family: 宋体;">图?2.?简化的时序图</span></strong></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;"><!--[if gte vml 1]>
<![endif]--></span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">关于时序图中需要说明的地方：</span></p>
<ol start="1" type="1">
    <li style="text-align: left;"><span style="font-size: 12pt; font-family: 宋体;">在contextManager初始化后会根据配置信息，加载基本的应用模块和各种监听器对象，创建钩子（Hook）机制，注册监听器对象，形成一个责任链。然后对各个监听器对象发出engineInit，engineStart消息。</span></li>
    <li style="text-align: left;"><span style="font-size: 12pt; font-family: 宋体;">一个请求在经过http10interceptor基本处理后提交到contextManager处理。</span></li>
    <li style="text-align: left;"><span style="font-size: 12pt; font-family: 宋体;">ContextManager</span><span style="font-size: 12pt; font-family: 宋体;">的processRequest方法进行请求的处理。按照处理的步骤会顺序地发出H_postReadRequest， H_contextMap， H_requestMap等消息。然后从hook中取得对该消息注册的监听器对象，调用他们的处理方法，从而实现责任链方式。以下的代码片断说明了这种方式：</span></li>
</ol>
<p style="margin-left: 36pt; text-align: left; text-indent: -18pt;" align="left"><span style="font-size: 12pt; font-family: 宋体;"><span>4.<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><span style="font-size: 12pt; font-family: 宋体;">BaseInterceptor
ri[];</span></p>
<p style="margin-left: 36pt; text-align: left; text-indent: -18pt;" align="left"><span style="font-size: 12pt; font-family: 宋体;"><span>5.<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><span style="font-size: 12pt; font-family: 宋体;">//</span><span style="font-size: 12pt; font-family: 宋体;">取得注册对象</span></p>
<p style="margin-left: 36pt; text-align: left; text-indent: -18pt;" align="left"><span style="font-size: 12pt; font-family: 宋体;"><span>6.<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><span style="font-size: 12pt; font-family: 宋体;">ri=defaultContainer.getInterceptors(Container.H_postReadRequest);</span></p>
<p style="margin-left: 36pt; text-align: left; text-indent: -18pt;" align="left"><span style="font-size: 12pt; font-family: 宋体;"><span>7.<span style="font-family: &quot;Times New Roman&quot;; font-style: normal; font-variant: normal; font-weight: normal; font-size: 7pt; line-height: normal; font-size-adjust: none; font-stretch: normal;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><span style="font-size: 12pt; font-family: 宋体;">//</span><span style="font-size: 12pt; font-family: 宋体;">执行注册对象的对消息的处理方法</span></p>
<p style="margin-left: 36pt; text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">for( int i=0; i&lt; ri.length; i++ ) {
status=ri[i].postReadRequest( req );&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ......}</span></p>
<ol start="8" type="1">
    <li style="text-align: left;"><span style="font-size: 12pt; font-family: 宋体;">系统退出时contextManager发出engineStop消息。</span></li>
</ol>
<p style="text-align: left;" align="left"><strong><span style="background: #ffff66 none repeat scroll 0% 50%; font-size: 12pt; font-family: 宋体; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong><span style="font-size: 12pt; font-family: 宋体;">3.3</span><span style="font-size: 12pt; font-family: 宋体;">的基本程序<strong><span style="background: #a0ffff none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">结构</span></strong>就是采用上面介绍的方式设计的。它给我们的设计和开发提供了一个很好的思路，通过这种模式可以轻松的实现一个事件驱动的基于模块化设计的应用程序。各个功能通过模块实现，通过对责任链上的消息和处理步骤的改动或者添加新的监听器对象可以非常方便的扩展<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>的功能。所以这是一个非常好的设计。</span></p>
<p style="text-align: left;" align="left"><strong><span style="background: #ffff66 none repeat scroll 0% 50%; font-size: 13.5pt; font-family: 宋体; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong><strong><span style="font-size: 13.5pt; font-family: 宋体;">4.0</span></strong><strong><span style="font-size: 13.5pt; font-family: 宋体;">的基本<span style="background: #a0ffff none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">结构</span>设计</span></strong></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">虽然<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>3.x已经实现了一个非常好的设计体系，但是在Sun公司加入后， <strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>4.0中还是引入了不同的实现方式。主要的区别是<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>4.0采用了面向组件的设计方式， <strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>4.0中的功能是由组件提供的，控制流程通过组件之间的通讯完成。这不同于<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>3.3中的基于模块的链式控制<strong><span style="background: #a0ffff none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">结构</span></strong>。</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">面 向组件的技术(CO)是比面向对象的技术(OOP)更高一层的抽象，它融合了面向对象的优点，加入了安全性和可扩展的模块设计，可以更好的映射问题域空
间。采用面向组件的设计会带来很多好处，可以提高复用性、降低耦合度和通过组装构成系统等等。面向组件编程中有许多概念与原来面向对象的编程是不同的，例 如：</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">Message(</span><span style="font-size: 12pt; font-family: 宋体;">消息)：定义抽象操作；<span>
Method(</span>方法)：定义具体的操作； Interface(接口)：一组消息的集合； Implementation(实现)：一组方法的集合； Module(模块)：静态的数据<strong><span style="background: #a0ffff none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">结构</span></strong>, Type(类型)：动态的数据<strong><span style="background: #a0ffff none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">结构</span></strong>。</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">软件组件不同与功能模块，它具有以下特性：</span></p>
<ul type="disc">
    <li style="text-align: left;"><span style="font-size: 12pt; font-family: 宋体;">组件是一个自包容的模块，具有定义清楚的界线，对外提供它的能力、属性和事件。</span></li>
    <li style="text-align: left;"><span style="font-size: 12pt; font-family: 宋体;">组件自身不保留状态。</span></li>
    <li style="text-align: left;"><span style="font-size: 12pt; font-family: 宋体;">组件可以是一个类，大部分情况下是一组类。</span></li>
</ul>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">在<span>Java
</span>语言中对面向组件编程的支持是通过JavaBeans模型获得的。JavaBean组件框架提供了对事件和属性的支持。<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>4.0的组件的就是通过JavaBean技术实现的。这是它和<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>3.3中最大的不同。下面我们来看一下<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>4.0是如何通过面向组件编程来实现程序流程控制的。</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">面向组件编程时设计组件是关键，从<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>4.0中可以看出主要使用了以下的设计模式：</span></p>
<p style="text-align: left;" align="left"><strong><span style="font-size: 12pt; font-family: 宋体;">Separation of Concerns</span></strong><strong><span style="font-size: 12pt; font-family: 宋体;">（SOC）</span></strong></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">设计组件时应该从不同的问题领域，站在不同的观点上<strong><span style="background: #99ff99 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">分析</span></strong>，把每一种属性分别考虑。举一个例子FileLogger组件，它用于把系统日志信息保存到文件系统中。按照这种模式<strong><span style="background: #99ff99 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">分析</span></strong>，我们从不同的角度看待它：它如何启动服务、停止服务和进行通讯？它的具体的功能有哪些？别的组件可以发给它哪些消息？基于这些考虑，FileLogger组件应该实现两种接口：Lifecycle（生存期接口）和LoggerBase（功能接口）。</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">Inversion of Control</span><span style="font-size: 12pt; font-family: 宋体;">（IOC）这个模式定义的是，组件总是通过外部进行管理的。组件需要的信息总是来源于外部，实际上组件在生存期的各个阶段都是被创建它的组件管理的。在<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>4.0中就是通过这种组件之间的相互控制和调用实现各个功能的。</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">按照这些模式<strong><span style="background: #99ff99 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">分析</span></strong>得到的<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>4.0中的组件是既有共性又有特性。共性是Lifecycle接口，特性是不同的功能接口。其中生存期接口处理组件的整个生存期中的各个阶段的事件,功能接口提供给其他的组件使用。</span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">具体的功能如何实现我在这里不多介绍了，我主要介绍一下<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>4.0中组件的Lifecycle接口的设计。Lifecycle接口实现了组件的生存期管理，控制管理和通讯。创建一个软件组件和创建一个JavaBean对象一样，可以参考JavaBean进行理解。我通过一个模拟的 Lifecycle接口组件的类图来描述。(见图三)</span></p>
<p style="text-align: left;" align="left"><strong><span style="font-size: 12pt; font-family: 宋体;">图?3.?Lifecycle接口组件类图</span></strong></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;"><!--[if gte vml 1]>
<![endif]--></span></p>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">对模拟的Lifecycle接口组件的类图的说明</span></p>
<ol start="1" type="1">
    <li style="text-align: left;"><span style="font-size: 12pt; font-family: 宋体;">Lifecycle
    Interface(</span><span style="font-size: 12pt; font-family: 宋体;">接口)定义一组组件通讯的Message(消息)。</span></li>
    <li style="text-align: left;"><span style="font-size: 12pt; font-family: 宋体;">组件实现Lifecycle接口，组件内部定义一个LifecycleSupport对象。需要和该组件通讯的其他组件必须实现LifecycleListener接口，该组件通过add/removeLifecycleListener方法管理需要通讯的其他组件。</span></li>
    <li style="text-align: left;"><span style="font-size: 12pt; font-family: 宋体;">组件内部状态改变时如果需要和其他组件通讯时，通过LifecycleSupport对象的fireLifecycleEvent方法通知其他组件。</span></li>
    <li style="text-align: left;"><span style="font-size: 12pt; font-family: 宋体;">其他组件通过lifecycleEvent方法获得通知的消息。LifecycleEvent对象是从java.util.EventObject派生的。</span></li>
    <li style="text-align: left;"><span style="font-size: 12pt; font-family: 宋体;">当然在组件设计和实现中我们也可以直接使用JavaBeans中已经提供的的类如：java.beans.PropertyChangeListener；java.beans.PropertyChangeSupport这样可以获得更多的功能特性支持。</span></li>
</ol>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">通过上面的<strong><span style="background: #99ff99 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">分析</span></strong>我们可以看到组件成为<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>4.0中的核心概念，系统的功能都是通过组件实现的，组件之间的通讯构成了系统的运行控制机制。我们把 <strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>3.3中模块化的链状控制机制和<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>4.0的面向组件的设计进行比较，就会发现<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>4.0在设计思想上软件组件的概念非常明确。<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>4.0和<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>3.3最主要的区别就在于此。至于面向对象和面向组件的关系和区别，我在这里就不介绍了，有兴趣的朋友可以找到很多这方面的资源。</span></p>
<p style="text-align: left;" align="left"><strong><span style="font-size: 18pt; font-family: 宋体;">从<span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span>源码中得到高效的软件组件</span></strong></p>
<p style="text-align: left;" align="left"><strong><span style="background: #ffff66 none repeat scroll 0% 50%; font-size: 12pt; font-family: 宋体; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong><span style="font-size: 12pt; font-family: 宋体;">不但为我们提供了设计和实现系统时的新思路，同时因为它是由组件或者模块构成的，所以它还为我们提供了大量可用的高效软件组件。这些组件都可以在我们的程序开发中使用。我简单列举一些，需要时可以直接从源码中取得。</span></p>
<ul type="disc">
    <li style="text-align: left;"><span style="font-size: 12pt; font-family: 宋体;">一些特殊集合类数据<strong><span style="background: #a0ffff none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">结构</span></strong>如池、队列、缓存等可用于服务端开发。 "src"share"org"apache"<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">tomcat</span></strong>"util"collections</span></li>
    <li style="text-align: left;"><span style="font-size: 12pt; font-family: 宋体;">一个简单的钩子（Hooks）机制的实现。 src"share"org"apache"<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">tomcat</span></strong>"util"hooks</span></li>
    <li style="text-align: left;"><span style="font-size: 12pt; font-family: 宋体;">一个简单线程池（ThreadPool）的实现。 src"share"org"apache"<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">tomcat</span></strong>"util"threads</span></li>
    <li style="text-align: left;"><span style="font-size: 12pt; font-family: 宋体;">组件Lifecycle接口的设计和实现。 "src"catalina"src"share"org"apache"Catalina</span></li>
    <li style="text-align: left;"><span style="font-size: 12pt; font-family: 宋体;">常用的日志信息的管理（Logger）的实现。 src"catalina"src"share"org"apache"catalina"logger</span></li>
    <li style="text-align: left;"><span style="font-size: 12pt; font-family: 宋体;">对xml格式的配置信息进行处理（XmlMapper）的实现。<span>
    src"catalina"src"share"org"apache"catalina"util"xml</span></span></li>
    <li style="text-align: left;"><span style="font-size: 12pt; font-family: 宋体;">对socket通讯的高级管理和实现（net）。<span>
    "src"catalina"src"share"org"apache"catalina"net</span></span></li>
</ul>
<p style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">通过以上对<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>的简单的介绍，我们可以看出，作为一个开放源码的项目，<strong><span style="background: #ffff66 none repeat scroll 0% 50%; color: black; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">Tomcat</span></strong>不但为我们提供了一个应用的平台，同时它还为我们提供了一个学习和研究设计模式、面向组件技术等理论的实践平台。</span></p>
<img src ="http://www.blogjava.net/sutao/aggbug/143617.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/sutao/" target="_blank">苏醄</a> 2007-09-08 16:08 <a href="http://www.blogjava.net/sutao/articles/143617.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>