﻿<?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-xsong-随笔分类-tomcat</title><link>http://www.blogjava.net/ghost/category/48565.html</link><description /><language>zh-cn</language><lastBuildDate>Fri, 13 May 2011 04:21:18 GMT</lastBuildDate><pubDate>Fri, 13 May 2011 04:21:18 GMT</pubDate><ttl>60</ttl><item><title>Tomcat ClassLoader</title><link>http://www.blogjava.net/ghost/archive/2011/05/13/350153.html</link><dc:creator>xsong</dc:creator><author>xsong</author><pubDate>Fri, 13 May 2011 03:44:00 GMT</pubDate><guid>http://www.blogjava.net/ghost/archive/2011/05/13/350153.html</guid><wfw:comment>http://www.blogjava.net/ghost/comments/350153.html</wfw:comment><comments>http://www.blogjava.net/ghost/archive/2011/05/13/350153.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ghost/comments/commentRss/350153.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ghost/services/trackbacks/350153.html</trackback:ping><description><![CDATA[Tomcat Server在启动的时候将构造一个ClassLoader树，以保证模块的类库是私有的<br />
Tomcat Server的ClassLoader结构如下：
<div><span style="border-collapse: separate; color: #000000; font-family: Simsun; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; font-size: medium;"><span style="font-size: 12px;"><br />
</span></span></div>
<div><span style="border-collapse: separate; color: #000000; font-family: Simsun; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; font-size: medium;"><span style="font-size: 12px;"><img style="cursor: default; vertical-align: middle;" name="0950a143-c537-4770-8e95-88ee669d1140" src="https://www.evernote.com/shard/s68/res/0950a143-c537-4770-8e95-88ee669d1140.png" class="en-media" width="267" height="171"  alt="" /></span></span></div>
<div><span style="border-collapse: separate; color: #000000; font-family: Simsun; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; font-size: medium;"><span style="font-size: 12px;"><span style="border-collapse: separate; color: #000000; font-family: Simsun; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; font-size: medium;"><span style="font-size: 12px;">其中：<br />
- Bootstrap - 载入JVM自带的类和$JAVA_HOME/jre/lib/ext/*.jar<br />
- System - 载入$CLASSPATH/*.class<br />
- Common - 载入$CATALINA_HOME/common/...，它们对TOMCAT和所有的WEB APP都可见<br />
- Catalina - 载入$CATALINA_HOME/server/...，它们仅对TOMCAT可见，对所有的WEB APP都不可见<br />
- Shared - 载入$CATALINA_HOME/shared/...，它们仅对所有WEB APP可见，对TOMCAT不可见（也不必见）<br />
- WebApp? - 载入ContextBase?/WEB-INF/...，它们仅对该WEB APP可见</span></span></span></span></div>
<div><span style="border-collapse: separate; color: #000000; font-family: Simsun; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; font-size: medium;"><span style="font-size: 12px;"><span style="border-collapse: separate; color: #000000; font-family: Simsun; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; font-size: medium;"><span style="font-size: 12px;"><br />
</span></span></span></span></div>
<img src ="http://www.blogjava.net/ghost/aggbug/350153.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ghost/" target="_blank">xsong</a> 2011-05-13 11:44 <a href="http://www.blogjava.net/ghost/archive/2011/05/13/350153.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>tomcat 请求流程</title><link>http://www.blogjava.net/ghost/archive/2011/05/13/350154.html</link><dc:creator>xsong</dc:creator><author>xsong</author><pubDate>Fri, 13 May 2011 03:44:00 GMT</pubDate><guid>http://www.blogjava.net/ghost/archive/2011/05/13/350154.html</guid><wfw:comment>http://www.blogjava.net/ghost/comments/350154.html</wfw:comment><comments>http://www.blogjava.net/ghost/archive/2011/05/13/350154.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ghost/comments/commentRss/350154.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ghost/services/trackbacks/350154.html</trackback:ping><description><![CDATA[<div>
<p><span style="border-collapse: separate; color: #000000; font-family: Simsun; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; font-size: medium;">假设来自客户的请求为：<br />
http://localhost:8080/wsota/wsota_index.jsp<br />
</span></p>
<p><span style="border-collapse: separate; color: #000000; font-family: Simsun; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; font-size: medium;">1) 请求被发送到本机端口8080，被在那里侦听的Coyote HTTP/1.1 Connector获得<br />
2) Connector把该请求交给它所在的Service的Engine来处理，并等待来自Engine的回应<br />
3) Engine获得请求localhost/wsota/wsota_index.jsp，匹配它所拥有的所有虚拟主机Host<br />
4) Engine匹配到名为localhost的Host（即使匹配不到也把请求交给该Host处理，因为该Host被定义为该Engine的默认主机）<br />
5) localhost Host获得请求/wsota/wsota_index.jsp，匹配它所拥有的所有Context<br />
6) Host匹配到路径为/wsota的Context（如果匹配不到就把该请求交给路径名为""的Context去处理）<br />
7) path="/wsota"的Context获得请求/wsota_index.jsp，在它的mapping table中寻找对应的servlet<br />
8) Context匹配到URL PATTERN为*.jsp的servlet，对应于JspServlet类<br />
9) 构造HttpServletRequest对象和HttpServletResponse对象，作为参数调用JspServlet的doGet或doPost方法<br />
10)Context把执行完了之后的HttpServletResponse对象返回给Host<br />
11)Host把HttpServletResponse对象返回给Engine<br />
12)Engine把HttpServletResponse对象返回给Connector<br />
13)Connector把HttpServletResponse对象返回给客户browser</span></p>
</div>
<img src ="http://www.blogjava.net/ghost/aggbug/350154.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ghost/" target="_blank">xsong</a> 2011-05-13 11:44 <a href="http://www.blogjava.net/ghost/archive/2011/05/13/350154.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Bootstrap 的 init 方法中 通过反射动态调用 Catalina.start()</title><link>http://www.blogjava.net/ghost/archive/2011/05/13/350151.html</link><dc:creator>xsong</dc:creator><author>xsong</author><pubDate>Fri, 13 May 2011 03:31:00 GMT</pubDate><guid>http://www.blogjava.net/ghost/archive/2011/05/13/350151.html</guid><wfw:comment>http://www.blogjava.net/ghost/comments/350151.html</wfw:comment><comments>http://www.blogjava.net/ghost/archive/2011/05/13/350151.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ghost/comments/commentRss/350151.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ghost/services/trackbacks/350151.html</trackback:ping><description><![CDATA[<div>
<div>Bootstrap 的 init 方法中 通过反射动态调用&nbsp;Catalina.start()&nbsp;</div>
<div>Catalina 类 负责开始或者停止服务</div>
<div>
<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">&nbsp;Class</span><span style="color: #000000;">&lt;?&gt;</span><span style="color: #000000;">&nbsp;startupClass&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;catalinaLoader.loadClass(</span><span style="color: #000000;">"</span><span style="color: #000000;">org.apache.catalina.startup.Catalina</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
&nbsp;Object&nbsp;startupInstance&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;startupClass.newInstance();</span></div>
</div>
<div>Catalina 完成了3个任务&nbsp;</div>
<ul>
    <li>&nbsp;处理xml文件， load 方法中使用&nbsp;Digester 处理server.xml文件，转化为java对象</li>
</ul>
<div>if (getServer() == null) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; load();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</div>
<ul>
    <li>&nbsp;&nbsp; &nbsp;实例化一个server &nbsp;<br />
    </li>
</ul>
<br />
<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">&nbsp;getServer().start();</span></div>
<ul>
    <li>&nbsp;&nbsp; &nbsp; 给jvm 注册一个关闭 的Hook（钩子）</li>
</ul>
<div>
<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">Runtime.getRuntime().addShutdownHook(shutdownHook);</span></div>
</div>
<ul>
    <li>线程等待</li>
</ul>
<div>&nbsp;await(); &nbsp;调用 StandardServer 的 await() &nbsp; StandardServer 处理 Server相关的操作，</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/**<br />
&nbsp;&nbsp;&nbsp;&nbsp; * Wait until a proper shutdown command is received, then return.<br />
&nbsp;&nbsp;&nbsp;&nbsp; * This keeps the main thread alive - the thread pool listening for http<br />
&nbsp;&nbsp;&nbsp;&nbsp; * connections is daemon threads.<br />
&nbsp;&nbsp;&nbsp;&nbsp; */</div>
<div><span style="border-collapse: separate; color: #000000; font-family: 'Lucida Sans Typewriter'; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; font-size: medium;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;StandardServer.await() 处理 当前的主线程，即 启动 tomcat 的主线程</span></div>
<div>
<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;awaitSocket&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;ServerSocket(port,&nbsp;</span><span style="color: #000000;">1</span><span style="color: #000000;">,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;InetAddress.getByName(address));<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">catch</span><span style="color: #000000;">(&nbsp;IOException&nbsp;e&nbsp;)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;log.error(</span><span style="color: #000000;">"</span><span style="color: #000000;">StandardServer.await:&nbsp;create[</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;address&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">:</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;port&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">]:&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;e);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;awaitThread&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;Thread.currentThread();<br />
<br />
</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;Loop&nbsp;waiting&nbsp;for&nbsp;a&nbsp;connection&nbsp;and&nbsp;a&nbsp;valid&nbsp;command</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;(</span><span style="color: #000000;">!</span><span style="color: #000000;">stopAwait)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ServerSocket&nbsp;serverSocket&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;awaitSocket;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(serverSocket&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">break</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;Wait&nbsp;for&nbsp;the&nbsp;next&nbsp;connection</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Socket&nbsp;socket&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;StringBuilder&nbsp;command&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;StringBuilder();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;InputStream&nbsp;stream;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;socket&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;serverSocket.accept();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;socket.setSoTimeout(</span><span style="color: #000000;">10</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1000</span><span style="color: #000000;">);&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;Ten&nbsp;seconds</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stream&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;socket.getInputStream();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">catch</span><span style="color: #000000;">&nbsp;(AccessControlException&nbsp;ace)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;log.warn(</span><span style="color: #000000;">"</span><span style="color: #000000;">StandardServer.accept&nbsp;security&nbsp;exception:&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;ace.getMessage(),&nbsp;ace);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">continue</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">catch</span><span style="color: #000000;">&nbsp;(IOException&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(stopAwait)&nbsp;{<br />
</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;Wait&nbsp;was&nbsp;aborted&nbsp;with&nbsp;socket.close()</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">break</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;log.error(</span><span style="color: #000000;">"</span><span style="color: #000000;">StandardServer.await:&nbsp;accept:&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;e);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">break</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;Read&nbsp;a&nbsp;set&nbsp;of&nbsp;characters&nbsp;from&nbsp;the&nbsp;socket</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;expected&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1024</span><span style="color: #000000;">;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;Cut&nbsp;off&nbsp;to&nbsp;avoid&nbsp;DoS&nbsp;attack</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;(expected&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;shutdown.length())&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(random&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;random&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;Random();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;expected&nbsp;</span><span style="color: #000000;">+=</span><span style="color: #000000;">&nbsp;(random.nextInt()&nbsp;</span><span style="color: #000000;">%</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">1024</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">&nbsp;(expected&nbsp;</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">0</span><span style="color: #000000;">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;ch&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;stream.read();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">catch</span><span style="color: #000000;">&nbsp;(IOException&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;log.warn(</span><span style="color: #000000;">"</span><span style="color: #000000;">StandardServer.await:&nbsp;read:&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;e);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ch&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">-</span><span style="color: #000000;">1</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(ch&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">32</span><span style="color: #000000;">)&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;Control&nbsp;character&nbsp;or&nbsp;EOF&nbsp;terminates&nbsp;loop</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">break</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;command.append((</span><span style="color: #0000ff;">char</span><span style="color: #000000;">)&nbsp;ch);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;expected</span><span style="color: #000000;">--</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">finally</span><span style="color: #000000;">&nbsp;{<br />
</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;Close&nbsp;the&nbsp;socket&nbsp;now&nbsp;that&nbsp;we&nbsp;are&nbsp;done&nbsp;with&nbsp;it</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(socket&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;socket.close();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">catch</span><span style="color: #000000;">&nbsp;(IOException&nbsp;e)&nbsp;{<br />
</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;Ignore</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;Match&nbsp;against&nbsp;our&nbsp;command&nbsp;string</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">boolean</span><span style="color: #000000;">&nbsp;match&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;command.toString().equals(shutdown);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(match)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;log.info(sm.getString(</span><span style="color: #000000;">"</span><span style="color: #000000;">standardServer.shutdownViaPort</span><span style="color: #000000;">"</span><span style="color: #000000;">));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">break</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;log.warn(</span><span style="color: #000000;">"</span><span style="color: #000000;">StandardServer.await:&nbsp;Invalid&nbsp;command&nbsp;'</span><span style="color: #000000;">"</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;command.toString()&nbsp;</span><span style="color: #000000;">+</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">'&nbsp;received</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">finally</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ServerSocket&nbsp;serverSocket&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;awaitSocket;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;awaitThread&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;awaitSocket&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">;<br />
</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;Close&nbsp;the&nbsp;server&nbsp;socket&nbsp;and&nbsp;return</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(serverSocket&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">null</span><span style="color: #000000;">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">try</span><span style="color: #000000;">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;serverSocket.close();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: #0000ff;">catch</span><span style="color: #000000;">&nbsp;(IOException&nbsp;e)&nbsp;{<br />
</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;Ignore</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}</span></div>
</div>
</div>
<img src ="http://www.blogjava.net/ghost/aggbug/350151.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ghost/" target="_blank">xsong</a> 2011-05-13 11:31 <a href="http://www.blogjava.net/ghost/archive/2011/05/13/350151.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Servlet 工作原理</title><link>http://www.blogjava.net/ghost/archive/2011/05/13/350150.html</link><dc:creator>xsong</dc:creator><author>xsong</author><pubDate>Fri, 13 May 2011 03:29:00 GMT</pubDate><guid>http://www.blogjava.net/ghost/archive/2011/05/13/350150.html</guid><wfw:comment>http://www.blogjava.net/ghost/comments/350150.html</wfw:comment><comments>http://www.blogjava.net/ghost/archive/2011/05/13/350150.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ghost/comments/commentRss/350150.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ghost/services/trackbacks/350150.html</trackback:ping><description><![CDATA[<div><br />
<a name="fig1"><strong>&nbsp;Tomcat 容器模型</strong></a><strong><br />
<br />
从上图中可以看出 Tomcat 的心脏是两个组件：Connector 和 Container多个 Connector 和一个 Container 就形成了一个 Service，有了 Service 就可以对外提供服务了。但是 Service 还要一个生存的环境，必须要有人能够给她生命、掌握其生死大权，那就非 Server 莫属了。所以整个 Tomcat 的生命周期由 Server 控制</strong></div>
<div><strong>从 Service &nbsp;</strong>
<div style="display: inline ! important;" _mce_style="display: inline !important;">
<div style="display: inline ! important;" _mce_style="display: inline !important;">
<div style="display: inline ! important;" _mce_style="display: inline !important;"><strong><span style="border-collapse: separate; color: rgb(0, 0, 0); font-family: 'Lucida Sans Typewriter'; font-style: normal; font-variant: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; font-size: medium;" _mce_style="border-collapse: separate; color: #000000; font-family: 'Lucida Sans Typewriter'; font-style: normal; font-variant: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; font-size: medium;">它主要是为了关联 Connector 和 Container。</span></strong></div>
</div>
</div>
</div>
<div><strong>Service 继承了&nbsp;</strong>
<div style="display: inline ! important;" _mce_style="display: inline !important;">
<div style="display: inline ! important;" _mce_style="display: inline !important;">
<div style="display: inline ! important;" _mce_style="display: inline !important;"><strong>Lifecycle接口</strong></div>
</div>
</div>
<div style="display: inline ! important;" _mce_style="display: inline !important;">
<div style="display: inline ! important;" _mce_style="display: inline !important;"><strong>&nbsp;， 这样所有实现 Service接口 组件的生命周期在一个 Lifecycle 的接口中控制，这里用到了一个重要的设计模式，关于这个接口将在后面介绍。</strong></div>
</div>
</div>
<div><br />
</div>
<div style="font-weight: bold;" _mce_style="font-weight: bold;"><img src="https://www.evernote.com/shard/s68/res/33367e3c-07c7-490c-a66b-d20c245dfb47.png" _mce_src="https://www.evernote.com/shard/s68/res/33367e3c-07c7-490c-a66b-d20c245dfb47.png" alt="" name="33367e3c-07c7-490c-a66b-d20c245dfb47" style="cursor: default; vertical-align: middle;" _mce_style="cursor: default; vertical-align: middle;" width="305" height="304" /></div>
<div style="font-weight: bold;" _mce_style="font-weight: bold;"><br />
</div>
<div><strong>Tomcat 中 Service 接口的标准实现类是 StandardService 它不仅实现了 Service 借口同时还实现了 Lifecycle 接口，这样它就可以控制它下面的组件的生命周期了。</strong></div>
<div><strong>Server 要完成的任务很简单，就是要能够提供一个接口让其它程序能够访问到这个 Service 集合、同时要维护它所包含的所有 Service 的生命周期，包括如何初始化、如何结束服务、如何找到别人要访问的 Service。</strong></div>
<div><strong>StandardServer doc:<br />
Standard implementation of the Server interface, available for use (but not required) when deploying and starting Catalina.<br />
StandardServer 类实现了 Server 接口，部署和启动tomcat实例</strong></div>
<div><strong><img src="https://www.evernote.com/shard/s68/res/87cd9dd3-6394-4e2a-b259-03697afbbc45.png" _mce_src="https://www.evernote.com/shard/s68/res/87cd9dd3-6394-4e2a-b259-03697afbbc45.png" alt="" name="87cd9dd3-6394-4e2a-b259-03697afbbc45" style="cursor: default; vertical-align: middle;" _mce_style="cursor: default; vertical-align: middle;" width="344" height="348" /><a name="minor1.3"><br />
</a></strong></div>
<div><strong><a name="minor1.3">组件的生命线&#8220;Lifecycle&#8221;&nbsp;</a></strong></div>
<div><strong><a name="minor1.3">Tomcat 中组件的生命周期是通过 Lifecycle 接口来控制的,除了控制生命周期的 Start 和 Stop 方法外还有一个监听机制,这个机制在其它的框架中也被使用，如在 Spring 中<br />
</a></strong></div>
<div><strong><img src="https://www.evernote.com/shard/s68/res/39b9d3fe-9d21-4cb9-bf68-46223ea6d608.png" _mce_src="https://www.evernote.com/shard/s68/res/39b9d3fe-9d21-4cb9-bf68-46223ea6d608.png" alt="" name="39b9d3fe-9d21-4cb9-bf68-46223ea6d608" style="cursor: default; vertical-align: middle;" _mce_style="cursor: default; vertical-align: middle;" width="328" height="166" /></strong></div>
<div><strong><a name="major2">Connector 组件<br />
</a></strong></div>
<div><strong><img src="https://www.evernote.com/shard/s68/res/848888f9-4243-4d5e-b986-ecbba09a86e6.png" _mce_src="https://www.evernote.com/shard/s68/res/848888f9-4243-4d5e-b986-ecbba09a86e6.png" alt="" name="848888f9-4243-4d5e-b986-ecbba09a86e6" style="cursor: default; vertical-align: middle;" _mce_style="cursor: default; vertical-align: middle;" width="864" height="784" /></strong></div>
<div><strong><br />
</strong><img src="https://www.evernote.com/shard/s68/res/b660e20e-9072-4894-b871-e69d078b69a4.jpg" _mce_src="https://www.evernote.com/shard/s68/res/b660e20e-9072-4894-b871-e69d078b69a4.jpg" alt="图 1 . Tomcat 容器模型" name="b660e20e-9072-4894-b871-e69d078b69a4" style="cursor: default; vertical-align: middle;" _mce_style="cursor: default; vertical-align: middle;" width="437" height="284" />
<div><br />
</div>
<div><br />
</div>
<div><br />
<div><br />
</div>
<div><a name="fig2"><strong>Tomcat 主要类的启动时序图</strong></a><br _mce_bogus="1" />
</div>
<div><img src="https://www.evernote.com/shard/s68/res/670366fc-1227-47c9-a733-c75fdebeb5d2.jpg?width=640&amp;height=615" _mce_src="https://www.evernote.com/shard/s68/res/670366fc-1227-47c9-a733-c75fdebeb5d2.jpg?width=640&amp;height=615" alt="http://www.ibm.com/developerworks/cn/java/j-lo-servlet/image003.jpg" name="670366fc-1227-47c9-a733-c75fdebeb5d2" style="cursor: default; vertical-align: middle;" _mce_style="cursor: default; vertical-align: middle;" width="640" height="615" /></div>
<div><br />
</div>
<div><strong>Tomcat 的启动逻辑是基于观察者模式设计的，所有的容器都会继承 Lifecycle 接口，它管理者容器的整个生命周期，所有容器的的修改和状态的改变都会由它去通知已经注册的观察者（Listener）</strong></div>
<div><strong>ContextConfig 的 init 方法将会主要完成以下工作：</strong></div>
<div>
<ol type="1">
    <li><strong>创建用于解析 xml 配置文件的 contextDigester 对象</strong></li>
    <li><strong>读取默认 context.xml 配置文件，如果存在解析它</strong></li>
    <li><strong>读取默认 Host 配置文件，如果存在解析它</strong></li>
    <li><strong>读取默认 Context 自身的配置文件，如果存在解析它</strong></li>
    <li><strong>设置 Context 的 DocBase</strong></li>
</ol>
<div>&nbsp;&nbsp; &nbsp;&nbsp;protected void init() {</div>
<div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;...<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: rgb(227, 0, 0);" _mce_style="color: #e30000;">contextConfig();</span><br />
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;...<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; }</div>
</div>
<div>&nbsp;&nbsp; &nbsp;&nbsp;protected void <span style="color: rgb(227, 0, 0);" _mce_style="color: #e30000;">contextConfig(</span>) {</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: rgb(150, 238, 125);" _mce_style="color: #96ee7d;">&nbsp;&nbsp;</span> <span style="color: rgb(77, 206, 29);" _mce_style="color: #4dce1d;">// 解析 content.xml&nbsp;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( defaultContextXml==null &amp;&amp; context instanceof StandardContext ) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; defaultContextXml = ((StandardContext)context).getDefaultContextXml();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // set the default if we don't have any overrides<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( defaultContextXml==null ) getDefaultContextXml();<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!context.getOverride()) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; File defaultContextFile = new File(defaultContextXml);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!defaultContextFile.isAbsolute()) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; defaultContextFile =new File(getBaseDir(), defaultContextXml);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (defaultContextFile.exists()) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; URL defaultContextUrl = defaultContextFile.toURI().toURL();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; processContextConfig(defaultContextUrl);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (MalformedURLException e) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; log.error(sm.getString(<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "contextConfig.badUrl", defaultContextFile), e);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp; &nbsp; <span style="color: rgb(77, 206, 29);" _mce_style="color: #4dce1d;">&nbsp; &nbsp; &nbsp; &nbsp;// &nbsp;解析 host</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; File hostContextFile = new File(getConfigBase(),<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getHostConfigPath(Constants.HostContextXml));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (hostContextFile.exists()) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; URL hostContextUrl = hostContextFile.toURI().toURL();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; processContextConfig(hostContextUrl);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (MalformedURLException e) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; log.error(sm.getString(<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "contextConfig.badUrl", hostContextFile), e);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</div>
<div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (context.getConfigFile() != null)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; processContextConfig(context.getConfigFile());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp; }</div>
<div>StandardContext 的&nbsp;startInternal&nbsp;方法&nbsp;主要包括如下几个部分：</div>
<div>
<ol type="1">
    <li><strong>创建读取资源文件的对象</strong></li>
    <li><strong>创建 ClassLoader 对象</strong></li>
    <li><strong>设置应用的工作目录</strong></li>
    <li><strong>启动相关的辅助类如：logger、realm、resources 等</strong></li>
    <li><strong>修改启动状态，通知感兴趣的观察者（Web 应用的配置）</strong></li>
    <li><strong>子容器的初始化</strong></li>
    <li><strong>获取 ServletContext 并设置必要的参数</strong></li>
    <li><strong>初始化&#8220;load on startup&#8221;的 Servlet</strong></li>
</ol>
<div>protected synchronized void startInternal() throws LifecycleException {</div>
<div><br />
</div>
<div>&nbsp;&nbsp; &nbsp; // 创建读取资源文件对象</div>
<div>&nbsp;&nbsp; &nbsp;&nbsp;if (webappResources == null) {&nbsp;&nbsp; // (1) Required by Loader
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (log.isDebugEnabled())<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; log.debug("Configuring default Resources");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((getDocBase() != null) &amp;&amp; (getDocBase().endsWith(".war")) &amp;&amp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (!(new File(getBasePath())).isDirectory()))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setResources(new WARDirContext());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setResources(new FileDirContext());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (IllegalArgumentException e) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; log.error("Error initializing resources: " + e.getMessage());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ok = false;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</div>
<div>&nbsp;&nbsp; &nbsp; // 创建classLoader</div>
<div>&nbsp;&nbsp; &nbsp;&nbsp;if (getLoader() == null) {</div>
<div><span style="border-collapse: separate; color: rgb(0, 0, 0); font-family: 'Lucida Sans Typewriter'; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; font-size: medium;" _mce_style="border-collapse: separate; color: #000000; font-family: 'Lucida Sans Typewriter'; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; font-size: medium;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WebappLoader webappLoader = new WebappLoader(getParentClassLoader());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; webappLoader.setDelegate(getDelegate());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setLoader(webappLoader);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
</span></div>
<div><span style="border-collapse: separate; color: rgb(0, 0, 0); font-family: 'Lucida Sans Typewriter'; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; font-size: medium;" _mce_style="border-collapse: separate; color: #000000; font-family: 'Lucida Sans Typewriter'; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; font-size: medium;"><br />
&nbsp;&nbsp;&nbsp; }</span></div>
<div><br />
</div>
&nbsp;&nbsp; &nbsp; //设置工作目录 &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</div>
<div>&nbsp;&nbsp; &nbsp; postWorkDirectory();</div>
<div>&nbsp;&nbsp; &nbsp; //启动相关的辅助类如：logger、realm、resources 等</div>
<div>&nbsp;&nbsp; &nbsp;&nbsp;if ((logger != null) &amp;&amp; (logger instanceof Lifecycle))</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((Lifecycle) logger).start();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((cluster != null) &amp;&amp; (cluster instanceof Lifecycle))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((Lifecycle) cluster).start();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((realm != null) &amp;&amp; (realm instanceof Lifecycle))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((Lifecycle) realm).start();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((resources != null) &amp;&amp; (resources instanceof Lifecycle))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((Lifecycle) resources).start();</div>
<div><br />
</div>
<div>&nbsp;&nbsp; &nbsp; //&nbsp;修改启动状态，通知感兴趣的观察者（Web 应用的配置）</div>
</div>
<div>&nbsp;&nbsp; &nbsp;&nbsp;fireLifecycleEvent(Lifecycle.CONFIGURE_START_EVENT, null);</div>
<div>&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//&nbsp;<span style="border-collapse: separate; color: rgb(0, 0, 0); font-family: 'Lucida Sans Typewriter'; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; font-size: medium;" _mce_style="border-collapse: separate; color: #000000; font-family: 'Lucida Sans Typewriter'; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; font-size: medium;">子容器的初始化</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Start our child containers, if not already started<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (Container child : findChildren()) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!child.getState().isAvailable()) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; child.start();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</div>
<div>&nbsp;&nbsp; &nbsp; // 注册集群管理</div>
<div>&nbsp;&nbsp; &nbsp;&nbsp;if (manager!=null &amp;&amp; (getCluster() != null) &amp;&amp; distributable) {</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //let the cluster know that there is a context that is distributable<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //and that it has its own manager<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getCluster().registerManager(manager);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</div>
</div>
</div>
<img src ="http://www.blogjava.net/ghost/aggbug/350150.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ghost/" target="_blank">xsong</a> 2011-05-13 11:29 <a href="http://www.blogjava.net/ghost/archive/2011/05/13/350150.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>