<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>我的随笔</title><link>http://webuc.net/simontaylor/category/41.aspx</link><description>长了这么大，也要给世界的穷苦大众留下一点东西了！</description><managingEditor>simontaylor（就是天寿）</managingEditor><dc:language>zh-CHS</dc:language><generator>.Text Version 0.95.2004.102</generator><item><dc:creator>simontaylor（就是天寿）</dc:creator><title>拿来主义！TOMCAT源码分析(消息处理) </title><link>http://webuc.net/simontaylor/articles/759.aspx</link><pubDate>Tue, 25 May 2004 13:04:00 GMT</pubDate><guid>http://webuc.net/simontaylor/articles/759.aspx</guid><wfw:comment>http://webuc.net/simontaylor/comments/759.aspx</wfw:comment><comments>http://webuc.net/simontaylor/articles/759.aspx#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://webuc.net/simontaylor/comments/commentRss/759.aspx</wfw:commentRss><trackback:ping>http://webuc.net/simontaylor/services/trackbacks/759.aspx</trackback:ping><description>&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;0：前言&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt; 
&lt;P class=MsoNormal style="TEXT-INDENT: 21pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;我们知道了tomcat的整体框架了， 也明白了里面都有些什么组件， 以及各个组件是干什么用的了。&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="TEXT-INDENT: 21pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;http://www.csdn.net/Develop/read_article.asp?id=27225&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="TEXT-INDENT: 21pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;我想，接下来我们应该去了解一下 tomcat 是如何处理jsp和servlet请求的。&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="TEXT-INDENT: 21pt; mso-layout-grid-align: none"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal style="mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;1. &lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;我们以一个具体的例子，来跟踪&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;TOMCAT&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;，&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt; &lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;看看它是如何把&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;Request&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;一层一层地递交给下一个容器，&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt; &lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;并最后交给&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;Wrapper&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;来处理的。&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 21pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;以&lt;/SPAN&gt;&lt;U&gt;&lt;SPAN style="COLOR: blue; mso-ansi-language: ZH-CN"&gt;http://localhost:8080/web/login.jsp&lt;/SPAN&gt;&lt;/U&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;为例子&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 21pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;（以下例子，&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt; &lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;都是以&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;tomcat4 &lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;源码为参考）&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 21pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;&amp;nbsp;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 21pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;这篇心得主要分为3个部分： 前期， 中期， 和末期。&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 21pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;前期：讲解了在浏览器里面输入一个URL，是怎么被tomcat抓住的。&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 21pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;中期：讲解了被tomcat抓住后，又是怎么在各个容器里面穿梭， 最后到达最后的处理地点。&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 21pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;末期：讲解到达最后的处理地点后，又是怎么具体处理的。&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 21pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;2&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;、&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.0pt; mso-ansi-language: ZH-CN"&gt;前期 Request的born.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 21pt; TEXT-INDENT: -21pt; mso-layout-grid-align: none; tab-stops: 21.0pt"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;在这里我先简单讲一下request这个东西。&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 21pt; TEXT-INDENT: -21pt; mso-layout-grid-align: none; tab-stops: 21.0pt"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;我们先看着这个URL：&lt;/SPAN&gt;&lt;U&gt;&lt;SPAN style="COLOR: blue; mso-ansi-language: ZH-CN"&gt;http://localhost:8080/web/login.jsp&lt;/SPAN&gt;&lt;/U&gt;&lt;SPAN style="COLOR: blue; mso-ansi-language: ZH-CN"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.0pt; mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;它是动用了8080端口来进行socket通讯的。&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 21pt; TEXT-INDENT: -21pt; mso-layout-grid-align: none; tab-stops: 21.0pt"&gt;&lt;SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.0pt; mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;我们知道, 通过 &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 21pt; TEXT-INDENT: -21pt; mso-layout-grid-align: none; tab-stops: 21.0pt"&gt;&lt;SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.0pt; mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;InputStream in = socket.getInputStream() 和&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 21pt; TEXT-INDENT: -21pt; mso-layout-grid-align: none; tab-stops: 21.0pt"&gt;&lt;SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.0pt; mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;OutputStream out = socket.getOutputStream() &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="TEXT-INDENT: -1.05pt; mso-char-indent-count: -.1; mso-char-indent-size: 10.5pt; mso-layout-grid-align: none; tab-stops: 21.0pt"&gt;&lt;SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.0pt; mso-ansi-language: ZH-CN"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;就可以实现消息的来来往往了。&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 21pt; TEXT-INDENT: -21pt; mso-layout-grid-align: none; tab-stops: 21.0pt"&gt;&lt;SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.0pt; mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;但是如果把Stream给应用层看，显然操作起来不方便。 &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 21pt; TEXT-INDENT: -21pt; mso-layout-grid-align: none; tab-stops: 21.0pt"&gt;&lt;SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.0pt; mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;所以，在tomcat 的Connector里面， socket被封装成了Request和Response这两个对象。&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 21pt; TEXT-INDENT: -21pt; mso-layout-grid-align: none; tab-stops: 21.0pt"&gt;&lt;SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.0pt; mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;我们可以简单地把Request看成管发到服务器来的数据，把Response看成想发出服务器的数据。&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 21pt; TEXT-INDENT: -21pt; mso-layout-grid-align: none; tab-stops: 21.0pt"&gt;&lt;SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.0pt; mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 21pt; TEXT-INDENT: -21pt; mso-layout-grid-align: none; tab-stops: 21.0pt"&gt;&lt;SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.0pt; mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;但是这样又有其他问题了啊？ Request这个对象是把socket封装起来了， 但是他提供的又东西太多了。&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 21pt; TEXT-INDENT: -21pt; mso-layout-grid-align: none; tab-stops: 21.0pt"&gt;&lt;SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.0pt; mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;诸如Request.getAuthorization(), Request.getSocket()。&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;像Authorization这种东西开发人员拿来基本上用不太着，而像socket这种东西，暴露给开发人员又有潜在的危险。 而且啊， 在Servlet Specification里面标准的通信类是ServletRequest和HttpServletRequest，而非这个Request类。 So, So, So. Tomcat必须得捣持捣持Request才行。 最后tomcat选择了使用捣持模式（应该叫适配器模式）来解决这个问题。它把org.apache.catalina.Request 捣持成了 org.apache.coyote.tomcat4.CoyoteRequest。 而CoyoteRequest又实现了ServletRequest和HttpServletRequest 这两种接口。 这样就提供给开发人员需要且刚刚需要的方法了。&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 21pt; TEXT-INDENT: -21pt; mso-layout-grid-align: none; tab-stops: 21.0pt"&gt;&lt;SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.0pt; mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 21pt; TEXT-INDENT: -21pt; mso-layout-grid-align: none; tab-stops: 21.0pt"&gt;&lt;SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.0pt; mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;ok, &lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.0pt; mso-ansi-language: ZH-CN"&gt;让&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;我们在 tomcat的顶层容器 - &lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;StandardEngin &lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.0pt; mso-ansi-language: ZH-CN"&gt;的invoke()方法这里设置一个断点， 然后访问&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 21pt; TEXT-INDENT: -21pt; mso-layout-grid-align: none; tab-stops: 21.0pt"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.0pt; mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;U&gt;&lt;SPAN style="COLOR: blue; mso-ansi-language: ZH-CN"&gt;http://localhost:8080/web/login.jsp&lt;/SPAN&gt;&lt;/U&gt;&lt;SPAN style="COLOR: blue; mso-ansi-language: ZH-CN"&gt; &lt;/SPAN&gt;&lt;SPAN style="COLOR: black; FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.0pt; mso-ansi-language: ZH-CN"&gt;， 我们来看看在前期都会路过哪些地方：&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="mso-layout-grid-align: none"&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;1. &lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;run(): 536, java.lang.Thread, Thread.java&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;CurrentThread&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="mso-layout-grid-align: none"&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;2.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;run():666, org.apache.tomcat.util.threads.ThreadPool$ControlRunnable, ThreadPool.java&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="mso-layout-grid-align: none"&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;ThreadPool&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="mso-layout-grid-align: none"&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;3.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;runIt():589, org.apache.tomcat.util.net.TcpWorkerThread, PoolTcpEndpoint.java&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="mso-layout-grid-align: none"&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;ThreadWorker&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 42pt; TEXT-INDENT: -20.25pt; mso-layout-grid-align: none; tab-stops: list 42.0pt; mso-list: l0 level1 lfo1"&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;4.&lt;SPAN style="FONT: 7pt 'Times New Roman'"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;processConnection(): &lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;549&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 21.75pt; TEXT-INDENT: 20.25pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler, Http11Protocol.java&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="mso-layout-grid-align: none"&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;http protocol parser&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="mso-layout-grid-align: none"&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;5.&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;Process(): 781, org.apache.coyote.http11.Http11Processor, Http11Processor.java&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="mso-layout-grid-align: none"&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;http request processor&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="mso-layout-grid-align: none"&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;6. service(): 193, org.apache.coyote.tomcat4.CoyoteAdapter,CoyoteAdapter.java&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="mso-layout-grid-align: none"&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/SPAN&gt;adapter&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="mso-layout-grid-align: none"&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;7. invoke(): 995, org.apache.catalina.core.ContainerBase, ContainerBase.java&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="TEXT-INDENT: 21pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;StandardEngin&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="TEXT-INDENT: 21pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;&amp;nbsp;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;1. 主线程&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;2. 启动线程池.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;3. 调出线程池里面空闲的工作线程。&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;4. 把8080端口传过来由httpd协议封装的数据，解析成Request和Response对象。&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;5. 使用&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;Http11Processor&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.0pt; mso-ansi-language: ZH-CN"&gt;来处理request&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.0pt; mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;6. 在&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;Http11Processor&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;里面， 又会call &lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;CoyoteAdapter&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;来进行适配处理，把Request适配成实现了ServletRequest和HttpServletRequest接口的&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;CoyoteRequest.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="TEXT-INDENT: 21pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;7&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;. 到了这里，前期的去毛拔皮工作就基本上搞定，可以交给&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;StandardEngin &lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;做核心的处理工作了。&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="TEXT-INDENT: 21pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;&amp;nbsp;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;3. 中期。 在各个容器间的穿梭。&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Request在各个容器里面的穿梭大致是这样一种方式：&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;每个容器里面都有一个管道（pipline）， 专门用来传送Request用的。&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;管道里面又有好几个阀门（valve）， 专门用来过滤Request用的。&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;在管道的低部通常都会放上一个默认的阀们。 这个阀们至少会做一件事情，就是把Request交给子容器。&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;让我们来想象一下：&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;当一个Request进入一个容器后， 它就在管道里面流动，波罗~ 波罗~ 波罗~ 地穿过各个阀门。在流到最后一个阀门的时候，吧唧~ 那个该死的阀门就把它扔给了子容器。 然后又开始 波罗~ 波罗~ 波罗~ ... 吧唧~....&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;波罗~&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;波罗~ 波罗~ ....吧唧~.... &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;就是通过这种方式， Request 走完了所有的容器。（ 感觉有点像消化系统，最后一个地方有点像那里~&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;）&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;OK， 让我们具体看看都有些什么容器， 各个容器里面又都有些什么阀门，这些阀们都对我们的Request做了些什么吧：&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="TEXT-INDENT: 21pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;&lt;/SPAN&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal style="TEXT-INDENT: 21pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;3.1 StandardEngin &lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;的pipeline里面放的是：&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;StandardEnginValve&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="TEXT-INDENT: 21pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;在这里，&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;VALVE&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;做了三件事：&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt; mso-layout-grid-align: none; tab-stops: 39.0pt"&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;1.&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;验证传递过来的&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;request&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;是不是&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;httpservletRequest.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt; mso-layout-grid-align: none; tab-stops: 39.0pt"&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;2&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;验证传递过来的&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt; request &lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;是否携带了&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;host header&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;信息&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt; mso-layout-grid-align: none; tab-stops: 39.0pt"&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;3&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;选择相应的&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;host&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;去处理它。（一般我们都只有一个host:&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;localhost&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;，也就是&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;127.0.0.1&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;）。&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="TEXT-INDENT: 21.3pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;到了这个地方，&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt; &lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;我们的&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;request&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;就已经完成了在&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;Engin&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;这个部分的历史使命，&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt; &lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;通向前途未卜的下一站：&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt; host&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;了。&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="TEXT-INDENT: 21.3pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;&amp;nbsp;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 21pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;3.2 StandardHost &lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;的pipline里面放的是：&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt; StandardHostValve&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt; mso-layout-grid-align: none; tab-stops: 39.0pt"&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;1.&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;验证传递过来的&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;request&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;是不是&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;httpservletRequest.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt; mso-layout-grid-align: none; tab-stops: 39.0pt"&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;2.&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;根据&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;Request&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;来确定哪个&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;Context&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;来处理。&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 39pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;Context&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;其实就是&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;webapp&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;，&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt; &lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;比如&lt;/SPAN&gt;&lt;U&gt;&lt;SPAN style="COLOR: blue; mso-ansi-language: ZH-CN"&gt;http://localhost:8080/web/login.jsp&lt;/SPAN&gt;&lt;/U&gt;&lt;SPAN style="COLOR: blue; mso-ansi-language: ZH-CN"&gt; &lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 39pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;这里&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;web&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;就是&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;Context&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;罗！&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt; mso-layout-grid-align: none; tab-stops: 39.0pt"&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;3.&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;既然确定了是哪个&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;Context&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;了，那么就应该把那个&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;Context&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;的&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;classloader&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;付给当前线程了。&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt; &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt; mso-layout-grid-align: none; tab-stops: 39.0pt"&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Thread.currentThread().setContextClassLoader(context.getLoader().getClassLoader());&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt; mso-layout-grid-align: none; tab-stops: 39.0pt"&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;这样&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;request&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;就只看得见指定的&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;context&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;下面的&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;classes&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;啊，&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt; jar&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;啊这些，&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt; &lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;而看不见&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;tomcat&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;本身的类，&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt; &lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;什么&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;Engin&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;啊，&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt; Valve&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;啊。&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt; &lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;不然还得了啊！&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt; mso-layout-grid-align: none; tab-stops: 39.0pt"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;4. 既然request到了这里了，看来用户是准备访问web这个web app了，咋们得更新一下这个用户的session不是！ Ok , 就由manager更新一下用户的session信息&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt; mso-layout-grid-align: none; tab-stops: 39.0pt"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;5. 交给具体的Context 容器去继续处理Request.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt; mso-layout-grid-align: none; tab-stops: 39.0pt"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;6. Context处理完毕了，把&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;classloader&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;还回来。&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 21pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;&amp;nbsp;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 21pt; mso-layout-grid-align: none"&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;3.3 StandardContext &lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;的pipline里面放的是：&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt; StandardContextValve&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt; mso-layout-grid-align: none; tab-stops: 39.0pt"&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;1.&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;验证传递过来的&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;request&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;是不是&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;httpservletRequest.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt; mso-layout-grid-align: none; tab-stops: 39.0pt"&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;2.&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;如果&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;request&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;意图不轨，想要访问&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;/meta-inf, /web-inf&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;这些目录下的东西，呵呵，没有用D!&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt; mso-layout-grid-align: none; tab-stops: 39.0pt"&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;3.&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;这个时候就会根据&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;Request&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;到底是&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;Servlet&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;，&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;还是&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;jsp&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;，&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;还是静态资源来决定到底用哪种&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;Wrapper&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;来处理这个&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;Reqeust&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;了。&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt; mso-layout-grid-align: none; tab-stops: 39.0pt"&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;4.&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;一旦决定了到底用哪种&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;Wrapper&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;，&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;OK&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;，交给那个&lt;/SPAN&gt;&lt;SPAN style="mso-ansi-language: ZH-CN"&gt;Wrapper&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;处理。&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 39pt; TEXT-INDENT: -39pt; mso-layout-grid-align: none; tab-stops: 39.0pt"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;&amp;nbsp;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 39pt; TEXT-INDENT: -39pt; mso-layout-grid-align: none; tab-stops: 39.0pt"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;4. 末期。 不同的需求是怎么处理的.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt; mso-layout-grid-align: none; tab-stops: 39.0pt"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;StandardWrapper&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt; mso-layout-grid-align: none; tab-stops: 39.0pt"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;之前对Wrapper没有做过讲解，其实它是这样一种东西。&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt; mso-layout-grid-align: none; tab-stops: 39.0pt"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;我们在处理Request的时候，可以分成3种。&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt; mso-layout-grid-align: none; tab-stops: 39.0pt"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;处理静态的： &lt;SPAN style="mso-tab-count: 1"&gt;&lt;/SPAN&gt;org.apache.catalina.servlets.DefaultServlet&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt; mso-layout-grid-align: none; tab-stops: 39.0pt"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;处理jsp的：&lt;SPAN style="mso-tab-count: 1"&gt; &lt;/SPAN&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&lt;/SPAN&gt;org.apache.jasper.servlet.JspServlet &lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt; mso-layout-grid-align: none; tab-stops: 39.0pt"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;处理servlet的：&lt;SPAN style="mso-tab-count: 1"&gt; &lt;/SPAN&gt;org.apache.catalina.servlets.InvokerServlet&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt; mso-layout-grid-align: none; tab-stops: 39.0pt"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;不同的request就用这3种不同的servlet去处理。&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt; mso-layout-grid-align: none; tab-stops: 39.0pt"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;Wrapper就是对它们的一种简单的封装，有了Wrapper后，我们就可以轻松地拦截每次的Request。也可以容易地调用servlet的init()和destroy()方法， 便于管理嘛！&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt; mso-layout-grid-align: none; tab-stops: 39.0pt"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;具体情况是这么滴：&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt; mso-layout-grid-align: none; tab-stops: 39.0pt"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;如果request是找jsp文件，StandardWrapper里面就会封装一个org.apache.jasper.servlet.JspServlet去处理它。&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt; mso-layout-grid-align: none; tab-stops: 39.0pt"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;如果request是找 静态资源 ，StandardWrapper里面就会封装一个org.apache.jasper.servlet.DefaultServlet&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp; &lt;/SPAN&gt;去处理它。&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt; mso-layout-grid-align: none; tab-stops: 39.0pt"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;如果request是找servlet ，StandardWrapper里面就会封装一个org.apache.jasper.servlet.InvokerServlet 去处理它。&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt; mso-layout-grid-align: none; tab-stops: 39.0pt"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;&amp;nbsp;&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt; mso-layout-grid-align: none; tab-stops: 39.0pt"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;StandardWrapper同样也是容器，既然是容器， 那么里面一定留了一个管道给request去穿，管道低部肯定也有一个阀门(注1)，用来做最后一道拦截工作.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt; mso-layout-grid-align: none; tab-stops: 39.0pt"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;在这最底部的阀门里，其实就主要做了两件事:&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt; mso-layout-grid-align: none; tab-stops: 39.0pt"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;一是启动过滤器，让request在N个过滤器里面筛一通，如果OK！ 那就PASS。 否则就跳到其他地方去了。&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt; mso-layout-grid-align: none; tab-stops: 39.0pt"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;二是servlet.service((HttpServletRequest) request,(HttpServletResponse) response); 这个方法.&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt; mso-layout-grid-align: none; tab-stops: 39.0pt"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;如果是 JspServlet， 那么先把jsp文件编译成servlet_xxx, 再invoke servlet_xxx的servie()方法。&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt; mso-layout-grid-align: none; tab-stops: 39.0pt"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;如果是 DefaultServlet， 就直接找到静态资源，取出内容， 发送出去。&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt; mso-layout-grid-align: none; tab-stops: 39.0pt"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;如果是 InvokerServlet， 就调用那个具体的servlet的service()方法。&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt; mso-layout-grid-align: none; tab-stops: 39.0pt"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-spacerun: yes"&gt;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;ok! 完毕。&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt; mso-layout-grid-align: none; tab-stops: 39.0pt"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;注1: StandardWrapper 里面的阀门是最后一道关口了。 如果这个阀门欲意把request交给StandardWrapper 的子容器处理。 对不起， 在设计考虑的时候， Wrapper就被考虑成最末的一个容器， 压根儿就不会给Wrapper添加子容器的机会！ 如果硬是要调用addChild(), 立马抛出IllegalArgumentException！&lt;o:p&gt;&lt;/o:p&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt; mso-layout-grid-align: none; tab-stops: 39.0pt"&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;参考：&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt; mso-layout-grid-align: none; tab-stops: 39.0pt"&gt;&lt;FONT color=#0a0011&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: ZH-CN"&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;&lt;SPAN style="mso-tab-count: 1"&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 9.0pt"&gt;&lt;/FONT&gt;&lt;FONT color=#0a0011&gt;&amp;lt;&lt;/FONT&gt;&lt;A href="http://jakarta.apache.org/tomcat/"&gt;&lt;FONT color=#0a0011&gt;http://jakarta.apache.org/tomcat/&lt;/FONT&gt;&lt;/A&gt;&lt;FONT color=#0a0011&gt;&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;&lt;/FONT&gt;&lt;A href="http://www.onjava.com/pub/a/onjava/2003/05/14/java_webserver.html"&gt;&lt;FONT color=#0a0011&gt;http://www.onjava.com/pub/a/onjava/2003/05/14/java_webserver.html&lt;/FONT&gt;&lt;/A&gt;&lt;FONT color=#0a0011&gt;&amp;gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal style="MARGIN-LEFT: 39pt; TEXT-INDENT: -18pt; mso-layout-grid-align: none; tab-stops: 39.0pt"&gt;&lt;SPAN lang=EN-US style="COLOR: #333333; FONT-FAMILY: Arial; mso-bidi-font-size: 9.0pt"&gt;&lt;FONT color=#0a0011&gt;&lt;o:p&gt;&lt;SPAN lang=EN-US style="FONT-SIZE: 10.5pt; COLOR: #333333; FONT-FAMILY: 宋体; mso-bidi-font-family: Arial; mso-bidi-font-size: 9.0pt; mso-font-kerning: 1.0pt; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA"&gt;&lt;A href="http://www.csdn.net/Develop/read_article.asp?id=27225"&gt;TOMCAT源码分析(启动框架)&lt;/A&gt;&lt;/SPAN&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;img src ="http://webuc.net/simontaylor/aggbug/759.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>simontaylor（就是天寿）</dc:creator><title>看到了，拿来主义！·TOMCAT源码分析(启动框架)</title><link>http://webuc.net/simontaylor/articles/758.aspx</link><pubDate>Tue, 25 May 2004 13:03:00 GMT</pubDate><guid>http://webuc.net/simontaylor/articles/758.aspx</guid><wfw:comment>http://webuc.net/simontaylor/comments/758.aspx</wfw:comment><comments>http://webuc.net/simontaylor/articles/758.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://webuc.net/simontaylor/comments/commentRss/758.aspx</wfw:commentRss><trackback:ping>http://webuc.net/simontaylor/services/trackbacks/758.aspx</trackback:ping><description>&lt;P&gt;TOMCAT源码分析(启动框架)&lt;BR&gt;前言：&lt;BR&gt;&amp;nbsp;&amp;nbsp; 本文是我阅读了TOMCAT源码后的一些心得。 主要是讲解TOMCAT的系统框架， 以及启动流程。若有错漏之处，敬请批评指教！&lt;BR&gt;建议：&lt;BR&gt;&amp;nbsp;&amp;nbsp; 毕竟TOMCAT的框架还是比较复杂的， 单是从文字上理解， 是不那么容易掌握TOMCAT的框架的。 所以得实践、实践、再实践。 建议下载一份TOMCAT的源码， 调试通过， 然后单步跟踪其启动过程。 如果有不明白的地方， 再来查阅本文， 看是否能得到帮助。 我相信这样效果以及学习速度都会好很多！&lt;BR&gt;&amp;nbsp;&amp;nbsp; &lt;BR&gt;1. Tomcat的整体框架结构&lt;BR&gt;&amp;nbsp;&amp;nbsp; Tomcat的基本框架， 分为4个层次。&lt;BR&gt;&amp;nbsp;&amp;nbsp; Top Level Elements:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Server&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Service&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp; Connector&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; HTTP&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; AJP&lt;BR&gt;&amp;nbsp;&amp;nbsp; Container&lt;BR&gt;&amp;nbsp;&amp;nbsp; Engine&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Host&lt;BR&gt;&amp;nbsp;&amp;nbsp; Context&lt;BR&gt;&amp;nbsp;&amp;nbsp; Component&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; manager&lt;BR&gt;&amp;nbsp;&amp;nbsp; logger&lt;BR&gt;&amp;nbsp;&amp;nbsp; loader&lt;BR&gt;&amp;nbsp;&amp;nbsp; pipeline&lt;BR&gt;&amp;nbsp;&amp;nbsp; valve&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;BR&gt;&amp;nbsp;&amp;nbsp; 站在框架的顶层的是Server和Service&lt;BR&gt;&amp;nbsp;&amp;nbsp; Server:&amp;nbsp; 其实就是BackGroud程序， 在Tomcat里面的Server的用处是启动和监听服务端事件（诸如重启、关闭等命令。 在tomcat的标准配置文件：server.xml里面， 我们可以看到&amp;#8220;&amp;lt;Server port="8005" shutdown="SHUTDOWN" debug="0"&amp;gt;&amp;#8221;这里的"SHUTDOWN"就是server在监听服务端事件的时候所使用的命令字）&lt;BR&gt;&amp;nbsp;&amp;nbsp; Service： 在tomcat里面， service是指一类问题的解决方案。&amp;nbsp; 通常我们会默认使用tomcat提供的：Tomcat-Standalone 模式的service。 在这种方式下的service既给我们提供解析jsp和servlet的服务， 同时也提供给我们解析静态文本的服务。&lt;BR&gt;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp; Connector: Tomcat都是在容器里面处理问题的， 而容器又到哪里去取得输入信息呢？&lt;BR&gt;Connector就是专干这个的。 他会把从socket传递过来的数据， 封装成Request, 传递给容器来处理。&lt;BR&gt;&amp;nbsp;&amp;nbsp; 通常我们会用到两种Connector,一种叫http connectoer， 用来传递http需求的。 另一种叫AJP， 在我们整合apache与tomcat工作的时候， apache与tomcat之间就是通过这个协议来互动的。 （说到apache与tomcat的整合工作， 通常我们的目的是为了让apache 获取静态资源， 而让tomcat来解析动态的jsp或者servlet。）&lt;BR&gt;&amp;nbsp;&amp;nbsp; Container: 当http connector把需求传递给顶级的container: Engin的时候， 我们的视线就应该移动到Container这个层面来了。&lt;BR&gt;&amp;nbsp;&amp;nbsp; 在Container这个层， 我们包含了3种容器： Engin, Host, Context.&lt;BR&gt;&amp;nbsp;&amp;nbsp; Engin: 收到service传递过来的需求， 处理后， 将结果返回给service( service 是通过 connector 这个媒介来和Engin互动的 ).&lt;BR&gt;&amp;nbsp;&amp;nbsp; Host: Engin收到service传递过来的需求后，不会自己处理， 而是交给合适的Host来处理。&lt;BR&gt;Host在这里就是虚拟主机的意思， 通常我们都只会使用一个主机，既&amp;#8220;localhost&amp;#8221;本地机来处理。 &lt;BR&gt;&amp;nbsp;&amp;nbsp; Context: Host接到了从Host传过来的需求后， 也不会自己处理， 而是交给合适的Context来处理。 &lt;BR&gt;&amp;nbsp;&amp;nbsp; 比如： &amp;lt;&lt;A href="http://127.0.0.1:8080/foo/index.jsp"&gt;http://127.0.0.1:8080/foo/index.jsp&lt;/A&gt;&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;A href="http://127.0.1:8080/bar/index.jsp"&gt;http://127.0.1:8080/bar/index.jsp&lt;/A&gt;&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp; 前者交给foo这个Context来处理， 后者交给bar这个Context来处理。&lt;BR&gt;&amp;nbsp;&amp;nbsp; 很明显吧！ context的意思其实就是一个web app的意思。&lt;BR&gt;&amp;nbsp;&amp;nbsp; 我们通常都会在server.xml里面做这样的配置&lt;BR&gt;&amp;nbsp;&amp;nbsp; &amp;lt;Context path="/foo" docBase="D:/project/foo/web" /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp; 这个context容器，就是用来干我们该干的事儿的地方的。&lt;BR&gt;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp; Compenent: 接下来， 我们继续讲讲component是干什么用的。&lt;BR&gt;&amp;nbsp;&amp;nbsp; 我们得先理解一下容器和组件的关系。&lt;BR&gt;&amp;nbsp;&amp;nbsp; 需求被传递到了容器里面， 在合适的时候， 会传递给下一个容器处理。&lt;BR&gt;&amp;nbsp;&amp;nbsp; 而容器里面又盛装着各种各样的组件， 我们可以理解为提供各种各样的增值服务。&lt;BR&gt;&amp;nbsp;&amp;nbsp; manager: 当一个容器里面装了manager组件后，这个容器就支持session管理了， 事实上在tomcat里面的session管理， 就是靠的在context里面装的manager component.&lt;BR&gt;&amp;nbsp;&amp;nbsp; logger: 当一个容器里面装了logger组件后， 这个容器里所发生的事情， 就被该组件记录下来啦！ 我们通常会在logs/ 这个目录下看见 catalina_log.time.txt 以及 localhost.time.txt 和localhost_examples_log.time.txt。 这就是因为我们分别为：engin, host以及context(examples)这三个容器安装了logger组件， 这也是默认安装， 又叫做标配 ：）&lt;BR&gt;&amp;nbsp;&amp;nbsp; loader: loader这个组件通常只会给我们的context容器使用， loader是用来启动context以及管理这个context的classloader用的。&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; pipline: pipeline是这样一个东西， 当一个容器决定了要把从上级传递过来的需求交给子容器的时候， 他就把这个需求放进容器的管道(pipeline)里面去。 而需求傻呼呼得在管道里面流动的时候， 就会被管道里面的各个阀门拦截下来。 比如管道里面放了两个阀门。 第一个阀门叫做&amp;#8220;access_allow_vavle&amp;#8221;， 也就是说需求流过来的时候，它会看这个需求是哪个IP过来的， 如果这个IP已经在黑名单里面了， sure, 杀！ 第二个阀门叫做&amp;#8220;defaul_access_valve&amp;#8221;它会做例行的检查， 如果通过的话，OK， 把需求传递给当前容器的子容器。 就是通过这种方式， 需求就在各个容器里面传递，流动， 最后抵达目的地的了。&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; valve: 就是上面所说的阀门啦。&lt;BR&gt;&amp;nbsp;&amp;nbsp; Tomcat里面大概就是这么些东西， 我们可以简单地这么理解tomcat的框架，它是一种自上而下， 容器里又包含子容器的这样一种结构。&lt;BR&gt;2. Tomcat的启动流程&lt;BR&gt;&amp;nbsp;&amp;nbsp; 这篇文章是讲tomcat怎么启动的，既然我们大体上了解了TOMCAT的框架结构了， 那么我们可以望文生意地就猜到tomcat的启动， 会先启动父容器，然后逐个启动里面的子容器。 启动每一个容器的时候， 都会启动安插在他身上的组件。 当所有的组件启动完毕， 所有的容器启动完毕的时候， tomcat本身也就启动完毕了。&lt;BR&gt;&amp;nbsp;&amp;nbsp; 顺理成章地， 我们同样可以猜到， tomcat的启动会分成两大部分， 第一步是装配工作。 第二步是启动工作。 &lt;BR&gt;&amp;nbsp;&amp;nbsp; 装配工作就是为父容器装上子容器， 为各个容器安插进组件的工作。 这个地方我们会用到digester模式， 至于digester模式什么， 有什么用， 怎么工作的. 请参考 &amp;lt;&lt;A href="http://software.ccidnet.com/pub/article/c322_a31671_p2.html"&gt;http://software.ccidnet.com/pub/article/c322_a31671_p2.html&lt;/A&gt;&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp; 启动工作是在装配工作之后， 一旦装配成功了， 我们就只需要点燃最上面的一根导线， 整个tomcat就会被激活起来。 这就好比我们要开一辆已经装配好了的汽车的时候一样，我们只要把钥匙插进钥匙孔，一拧，汽车的引擎就会发动起来，空调就会开起来， 安全装置就会生效， 如此一来，汽车整个就发动起来了。（这个过程确实和TOMCAT的启动过程不谋而和， 让我们不得不怀疑 TOMCAT的设计者是在GE做JAVA开发的）。&lt;BR&gt;2.1 一些有意思的名称：&lt;BR&gt;&amp;nbsp;&amp;nbsp; Catalina&lt;BR&gt;&amp;nbsp;&amp;nbsp; Tomcat&lt;BR&gt;&amp;nbsp;&amp;nbsp; Bootstrap&lt;BR&gt;&amp;nbsp;&amp;nbsp; Engin&lt;BR&gt;&amp;nbsp;&amp;nbsp; Host&lt;BR&gt;&amp;nbsp;&amp;nbsp; Context&lt;BR&gt;&amp;nbsp;&amp;nbsp; 他们的意思很有意思：&lt;BR&gt;&amp;nbsp;&amp;nbsp; Catalina: 远程轰炸机&lt;BR&gt;&amp;nbsp;&amp;nbsp; Tomcat: 熊猫轰炸机 -- 轰炸机的一种（这让我想起了让国人引以为豪的熊猫手机，是不是英文可以叫做tomcat??? ， 又让我想起了另一则广告： 波导-手机中的战斗机、波音-客机中的战斗机 ）&lt;BR&gt;&amp;nbsp;&amp;nbsp; Bootstap: 引导&lt;BR&gt;&amp;nbsp;&amp;nbsp; Engin: 发动机&lt;BR&gt;&amp;nbsp;&amp;nbsp; Host: 主机，领土&lt;BR&gt;&amp;nbsp;&amp;nbsp; Context: 内容， 目标， 上下文&lt;BR&gt;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp; ... 在许多许多年后， 现代人类已经灭绝。 后现代生物发现了这些单词零落零落在一块。 一个自以为聪明的家伙把这些东西翻译出来了： &lt;BR&gt;&amp;nbsp;&amp;nbsp; 在地勤人员的引导(bootstrap)下， 一架轰炸架(catalina)腾空跃起， 远看是熊猫轰炸机(tomcat)， 近看还是熊猫轰炸机！ 凭借着优秀的发动机技术(engin)， 这架熊猫轰炸机飞临了敌国的领土上空(host)， 对准目标(context)投下了毁天灭地的核弹头，波~ 现代生物就这么隔屁了~&lt;BR&gt;&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp; 综上所述， 这又不得不让人联想到GE是不是也参与了军事设备的生产呢？&lt;BR&gt;&amp;nbsp;&amp;nbsp; 反对美帝国主义！ 反对美霸权主义！ 和平万岁！ 自由万岁！&lt;BR&gt;&amp;nbsp;&amp;nbsp; &lt;BR&gt;2.2&amp;nbsp; 历史就是那么惊人的相似！ tomcat的启动就是从org.apache.catalina.startup.Bootstrap这个类悍然启动的！&lt;BR&gt;&amp;nbsp;&amp;nbsp; 在Bootstrap里做了两件事：&lt;BR&gt;&amp;nbsp;&amp;nbsp; 1. 指定了3种类型classloader:&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; commonLoader: common/classes、common/lib、common/endorsed&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; catalinaLoader: server/classes、server/lib、commonLoader&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sharedLoader：&amp;nbsp; shared/classes、shared/lib、commonLoader&lt;BR&gt;&amp;nbsp;&amp;nbsp; 2. 引导Catalina的启动。&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 用Reflection技术调用org.apache.catalina.startup.Catalina的process方法， 并传递参数过去。&lt;BR&gt;&amp;nbsp;&amp;nbsp; &lt;BR&gt;2.3 Catalina.java&lt;BR&gt;&amp;nbsp;&amp;nbsp; Catalina完成了几个重要的任务：&lt;BR&gt;&amp;nbsp;&amp;nbsp; 1. 使用Digester技术装配tomcat各个容器与组件。&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1.1&amp;nbsp;装配工作的主要内容是安装各个大件。 比如server下有什么样的servcie。 Host会容纳多少个context。 Context都会使用到哪些组件等等。 &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 1.2&amp;nbsp;同时呢， 在装配工作这一步， 还完成了mbeans的配置工作。 在这里，我简单地但不十分精确地描述一下mbean是什么，干什么用的。&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 我们自己生成的对象， 自己管理， 天经地义！ 但是如果我们创建了对象了， 想让别人来管， 怎么办呢？ 我想至少得告诉别人我们都有什么， 以及通过什么方法可以找到&amp;nbsp; 吧！ JMX技术给我们提供了一种手段。 JMX里面主要有3种东西。Mbean, agent, connector.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Mbean： 用来映射我们的对象。也许mbean就是我们创建的对象， 也许不是， 但有了它， 就可以引用到我们的对象了。&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Agent:&amp;nbsp; 通过它， 就可以找到mbean了。&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Connector: 连接Agent的方式。 可以是http的， 也可以是rmi的，还可以直接通过socket。&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 发生在tomcat 装配过程中的事情:&amp;nbsp; GlobalResourcesLifecycleListener 类的初始化会被触发：&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; protected static Registry registry = MBeanUtils.createRegistry();&amp;nbsp; 会运行&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; MBeanUtils.createRegistry()&amp;nbsp; 会依据/org/apache/catalina/mbeans/mbeans-descriptors.xml这个配置文件创建 mbeans. Ok, 外界就有了条途径访问tomcat中的各个组件了。（有点像后门儿）&lt;BR&gt;&amp;nbsp;&amp;nbsp; 2. 为top level 的server 做初始化工作。 实际上就是做通常会配置给service的两条connector.(http, ajp)&lt;BR&gt;&amp;nbsp;&amp;nbsp; 3. 从server这个容器开始启动， 点燃整个tomcat.&lt;BR&gt;&amp;nbsp;&amp;nbsp; 4. 为server做一个hook程序， 检测当server shutdown的时候， 关闭tomcat的各个容器用。&lt;BR&gt;&amp;nbsp;&amp;nbsp; 5. 监听8005端口， 如果发送"SHUTDOWN"（默认培植下字符串）过来， 关闭8005serverSocket。&lt;BR&gt;2.4 启动各个容器&lt;BR&gt;&amp;nbsp;&amp;nbsp; 1. Server&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 触发Server容器启动前(before_start)， 启动中(start)， 启动后(after_start)3个事件， 并运行相应的事件处理器。&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 启动Server的子容器：Servcie. &lt;BR&gt;&amp;nbsp;&amp;nbsp; 2. Service&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 启动Service的子容器：Engin&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 启动Connector&lt;BR&gt;&amp;nbsp;&amp;nbsp; 3. Engin&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 到了Engin这个层次，以及以下级别的容器， Tomcat就使用了比较一致的启动方式了。&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 首先，&amp;nbsp; 运行各个容器自己特有一些任务&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 随后，&amp;nbsp; 触发启动前事件&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 立即，&amp;nbsp; 设置标签，就表示该容器已经启动&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 接着，&amp;nbsp; 启动容器中的各个组件： loader, logger, manager等等&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 再接着，启动mapping组件。（注1）&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 紧跟着，启动子容器。&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 接下来，启动该容器的管道(pipline)&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 然后，&amp;nbsp; 触发启动中事件&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 最后，&amp;nbsp; 触发启动后事件。&lt;BR&gt;&amp;nbsp;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Engin大致会这么做， Host大致也会这么做， Context大致还是会这么做。 那么很显然地， 我们需要在这里使用到代码复用的技术。 tomcat在处理这个问题的时候， 漂亮地使用了抽象类来处理。 ContainerBase. 最后使得这部分完成复杂功能的代码显得干净利落， 干练爽快， 实在是令人觉得叹为观止， 细细品来， 直觉如享佳珍， 另人齿颊留香， 留恋往返啊！&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Engin的触发启动前事件里， 会激活绑定在Engin上的唯一一个Listener：EnginConfig。&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 这个EnginConfig类基本上没有做什么事情， 就是把EnginConfig的调试级别设置为和Engin相当。 另外就是输出几行文本， 表示Engin已经配置完毕， 并没有做什么实质性的工作。&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 注1: mapping组件的用处是， 当一个需求将要从父容器传递到子容器的时候， 而父容器又有多个子容器的话， 那么应该选择哪个子容器来处理需求呢？ 这个由mapping 组件来定夺。&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp; 4. Host&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 同Engin一样， 也是调用ContainerBase里面的start()方法， 不过之前做了些自个儿的任务,就是往Host这个容器的通道（pipline）里面， 安装了一个叫做&lt;BR&gt;&amp;nbsp;&amp;#8220;org.apache.catalina.valves.ErrorReportValve&amp;#8221;的阀门。&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 这个阀门的用处是这样的：&amp;nbsp; 需求在被Engin传递给Host后， 会继续传递给Context做具体的处理。 这里需求其实就是作为参数传递的Request, Response。 所以在context把需求处理完后， 通常会改动response。 而这个org.apache.catalina.valves.ErrorReportValve的作用就是检察response是否包含错误， 如果有就做相应的处理。&lt;BR&gt;&amp;nbsp;&amp;nbsp; 5. Context&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 到了这里， 就终于轮到了tomcat启动中真正的重头戏，启动Context了。&lt;BR&gt;&amp;nbsp;StandardContext.start() 这个启动Context容器的方法被StandardHost调用.&lt;BR&gt;&amp;nbsp;5.1 webappResources 该context所指向的具体目录&lt;BR&gt;&amp;nbsp;5.2 安装defaultContex, DefaultContext 就是默认Context。 如果我们在一个Host下面安装了DefaultContext，而且defaultContext里面又安装了一个数据库连接池资源的话。 那么其他所有的在该Host下的Context, 都可以直接使用这个数据库连接池， 而不用格外做配置了。&lt;BR&gt;&amp;nbsp; 5.3 指定Loader. 通常用默认的org.apache.catalina.loader.WebappLoader这个类。&amp;nbsp;&amp;nbsp; Loader就是用来指定这个context会用到哪些类啊， 哪些jar包啊这些什么的。&lt;BR&gt;&amp;nbsp;5.4 指定 Manager. 通常使用默认的org.apache.catalina.session. StandardManager 。 Manager是用来管理session的。&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 其实session的管理也很好实现。 以一种简单的session管理为例。 当需求传递过来的时候， 在Request对象里面有一个sessionId 属性。 OK， 得到这个sessionId后， 我们就可以把它作为map的key，而value我们可以放置一个HashMap. HashMap里边儿， 再放我们想放的东西。&lt;BR&gt;&amp;nbsp;5.5 postWorkDirectory (). Tomcat下面有一个work目录。 我们把临时文件都扔在那儿去。 这个步骤就是在那里创建一个目录。 一般说来会在%CATALINA_HOME%/work/Standalone\localhost\ 这个地方生成一个目录。&lt;BR&gt;5.6&amp;nbsp; Binding thread。到了这里， 就应该发生 class Loader 互换了。 之前是看得见tomcat下面所有的class和lib. 接下来需要看得见当前context下的class。 所以要设置contextClassLoader, 同时还要把旧的ClassLoader记录下来，因为以后还要用的。&lt;BR&gt;5.7&amp;nbsp; 启动 Loader. 指定这个Context具体要使用哪些classes， 用到哪些jar文件。 如果reloadable设置成了true, 就会启动一个线程来监视classes的变化， 如果有变化就重新启动Context。&lt;BR&gt;5.8&amp;nbsp; 启动logger&lt;BR&gt;5.9&amp;nbsp; 触发安装在它身上的一个监听器。&lt;BR&gt;&amp;nbsp;lifecycle.fireLifecycleEvent(START_EVENT, null); &lt;BR&gt;&amp;nbsp;作为监听器之一，ContextConfig会被启动. ContextConfig就是用来配置web.xml的。 比如这个Context有多少Servlet， 又有多少Filter， 就是在这里给Context装上去的。&lt;BR&gt;&amp;nbsp;5.9.1 defaultConfig. 每个context都得配置 tomcat/conf/web.xml 这个文件。&lt;BR&gt;&amp;nbsp;5.9.2 applicationConfig 配置自己的 WEB-INF/web.xml 文件&lt;BR&gt;5.9.3 validateSecurityRoles 权限验证。 通常我们在访问/admin 或者/manager的时候，需要用户要么是admin的要么是manager的， 才能访问。 而且我们还可以限制那些资源可以访问， 而哪些不能。 都是在这里实现的。&lt;BR&gt;5.9.4 tldScan: 扫描一下， 需要用到哪些标签(tag lab)&lt;BR&gt;5.10 启动 manager&lt;BR&gt;5.11 postWelcomeFiles() 我们通常会用到的3个启动文件的名称：&lt;BR&gt;index.html、index.htm、index.jsp 就被默认地绑在了这个context上&lt;BR&gt;&amp;nbsp;5.12 listenerStart 配置listener&lt;BR&gt;&amp;nbsp;5.13 filterStart 配置 filter&lt;BR&gt;&amp;nbsp;5.14 启动带有&amp;lt;load-on-startup&amp;gt;1&amp;lt;/load-on-startup&amp;gt;的Servlet.&lt;BR&gt;&amp;nbsp; 顺序是从小到大： 1,2,3&amp;#8230; 最后是0&lt;BR&gt;&amp;nbsp; 默认情况下， 至少会启动如下3个的Servlet: &lt;BR&gt;&amp;nbsp; org.apache.catalina.servlets.DefaultServlet&amp;nbsp;&amp;nbsp; &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 处理静态资源的Servlet. 什么图片啊， html啊， css啊， js啊都找他&lt;BR&gt;&amp;nbsp; org.apache.catalina.servlets.InvokerServlet&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 处理没有做Servlet Mapping的那些Servlet.&lt;BR&gt;&amp;nbsp; org.apache.jasper.servlet.JspServlet &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 处理JSP文件的.&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 5.15&amp;nbsp; 标识context已经启动完毕。&lt;BR&gt;&amp;nbsp;走了多少个步骤啊， Context总算是启动完毕喽。&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; OK! 走到了这里， 每个容器以及组件都启动完毕。 Tomcat终于不辞辛劳地为人民服务了！&lt;BR&gt;3. 参考文献：&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;A href="http://jakarta.apache.org/tomcat/"&gt;http://jakarta.apache.org/tomcat/&lt;/A&gt;&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;A href="http://www.onjava.com/pub/a/onjava/2003/05/14/java_webserver.html"&gt;http://www.onjava.com/pub/a/onjava/2003/05/14/java_webserver.html&lt;/A&gt;&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR&gt;4. 后记&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 这篇文章是讲解tomcat启动框架的，还有篇文章是讲解TOMCAT里面的消息处理流程的细节的。 文章内容已经写好了， 现在正在整理阶段。 相信很快就可以做出来， 大家共同研究共同进步。&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 这篇文章是独自分析TOMCAT源码所写的， 所以一定有地方是带有个人主观色彩， 难免会有片面之处。若有不当之处敬请批评指教，这样不仅可以使刚开始研究TOMCAT的兄弟们少走弯路， 我也可以学到东西。&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; MSN: &lt;A href="mailto:sojan_private@hotmail.com"&gt;sojan_private@hotmail.com&lt;/A&gt; &lt;BR&gt;&lt;/P&gt;&lt;img src ="http://webuc.net/simontaylor/aggbug/758.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>simontaylor（就是天寿）</dc:creator><title>郁闷中还要学习</title><link>http://webuc.net/simontaylor/archive/2004/05/18/688.aspx</link><pubDate>Tue, 18 May 2004 10:22:00 GMT</pubDate><guid>http://webuc.net/simontaylor/archive/2004/05/18/688.aspx</guid><wfw:comment>http://webuc.net/simontaylor/comments/688.aspx</wfw:comment><comments>http://webuc.net/simontaylor/archive/2004/05/18/688.aspx#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://webuc.net/simontaylor/comments/commentRss/688.aspx</wfw:commentRss><trackback:ping>http://webuc.net/simontaylor/services/trackbacks/688.aspx</trackback:ping><description>最近头说要尽快考试，争取在这个月末考试通过。头说考试费用公司全部报销，如果MCSE顺利通过还可以适当奖励一下。可是这些指示留住我的一个借口，如果我违约，公司要我全部返款。不知道我现在是不是要去报销，到目前为止，已经消耗掉三千左右了，难啊。就难在了抉择上。&lt;img src ="http://webuc.net/simontaylor/aggbug/688.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>simontaylor</dc:creator><title>这几天没有什么事情做。</title><link>http://webuc.net/simontaylor/archive/2004/04/21/424.aspx</link><pubDate>Wed, 21 Apr 2004 14:03:00 GMT</pubDate><guid>http://webuc.net/simontaylor/archive/2004/04/21/424.aspx</guid><wfw:comment>http://webuc.net/simontaylor/comments/424.aspx</wfw:comment><comments>http://webuc.net/simontaylor/archive/2004/04/21/424.aspx#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://webuc.net/simontaylor/comments/commentRss/424.aspx</wfw:commentRss><trackback:ping>http://webuc.net/simontaylor/services/trackbacks/424.aspx</trackback:ping><description>&lt;P&gt;这几天公司里面的任务完成，没有什么事情做！&lt;/P&gt;
&lt;P&gt;所以现在在学习一下exchange2k，正好在5。1以后不久可以准备考试。以后说不定就网管的方向了！&lt;/P&gt;&lt;img src ="http://webuc.net/simontaylor/aggbug/424.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>simontaylor</dc:creator><title>第一次登陆，以后有时间我增加内容。</title><link>http://webuc.net/simontaylor/archive/2004/04/06/202.aspx</link><pubDate>Tue, 06 Apr 2004 13:43:00 GMT</pubDate><guid>http://webuc.net/simontaylor/archive/2004/04/06/202.aspx</guid><wfw:comment>http://webuc.net/simontaylor/comments/202.aspx</wfw:comment><comments>http://webuc.net/simontaylor/archive/2004/04/06/202.aspx#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://webuc.net/simontaylor/comments/commentRss/202.aspx</wfw:commentRss><trackback:ping>http://webuc.net/simontaylor/services/trackbacks/202.aspx</trackback:ping><description>今天帐号开通，日积月累，是否可以小有所成？&lt;img src ="http://webuc.net/simontaylor/aggbug/202.aspx" width = "1" height = "1" /&gt;</description></item></channel></rss>