Tomcat源码阅读之实例化Container
2016-08-06 21:59
405 查看
Container组件在Tomcat中代表Servlet容器,其对应的接口名称为Container,所有的Servlet容器都必须要实现这个接口。实例化Container组件,也就是实例化Tomcat的四个Servlet容器,分别是Engine,Host,Context,Wrapper。对应的接口分别是Engine,Host,Context,Wrapper,都继承自Container接口,标准实现类分别为StandardEngine,StandardHost,StandardContext,StandardWrapper。这几个容器实例化过程都比较简单,基本都是设置下基础阀。关于阀的内容在阅读容器处理请求流程部分会详细讲解。
接着程序会加载conf目录下的server.xml。这个文件在Tomcat的load过程中非常重要,文件的主要结构如下:
看见这个文件的结构有没有一种似曾相识的感觉呢,是的,跟Tomcat的结构图如出一辙,其实这个文件的作用就是在实例化组件的时候设置相关属性的值。那么疑问就来了,上面不是组件都实例化完了吗,再读配置文件是不是迟了点。其实不是,前面讲的实例化其实只是设置实例化的规则,真正执行实例化这个操作是在digester.parse(inputSource)这一步,而读取配置文件的操作在这一步之前,因此并不会影响组件的实例化。
server.xml中的Server节点对应Server组件,其标准实现类为StandardServer类,Server节点的属性port和shutdown对应StandardServer类的port和shutdown属性,在实例化Server组件的时候,通过属性的set方法,将Server节点的属性赋值给StandardServer,并且会将五个Listener子节点通过addLifecycleListener方法添加到一个数组里。
Service节点对应Service组件,Service节点下有两类子节点,分别是Connector型和Container。其中Connector类型的节点有两个,一个支持HTTP/1.1协议,另一个支持AJP/1.3。实例化Http连接器的时候,也是通过set方法,分别设置Connector类的port和protocol等属性的值。其中port属性表示监听的端口号,Tomcat启动时报端口被占用的错误就是因为这个端口被其他程序占用了。Container类型的子节点默认有两个,Engine和Host,分别对应Engine容器和Host容器。实例化Engine的时候,设置默认host为localhost,并且设置容器的名字为Catalina。同样,实例化Host容器的时候,会分别设置appBase,unpackWARs,autoDeploy等属性的值。
在实例化组件的时候,很多属性都是有默认值的,现在我们知道了程序会使用server.xml中的值来覆盖默认值,那么如果我们想在实例化改时改变某些属性的值,就可以通过修改server.xml中的值来达到这个目的。
执行完digester.parse(inputSource)这句代码之后,Server,Service,Connector等组件将正式执行实例化操作。
那么组件都实例化完之后该执行什么操作呢?未完待续。。。。。。
public void load() { 。 。 。 略 Digester digester = createStartDigester(); InputSource inputSource = null; InputStream inputStream = null; File file = null; try { file = configFile(); inputStream = new FileInputStream(file); inputSource = new InputSource("file://" + file.getAbsolutePath()); } catch (Exception e) { ; } 。 。 。 略 try { inputSource.setByteStream(inputStream); digester.push(this); digester.parse(inputSource); inputStream.close(); } catch (Exception e) { log.warn("Catalina.start using " + getConfigFile() + ": " , e); return; } // Stream redirection initStreams(); // Start the new server if (getServer() instanceof Lifecycle) { try { getServer().initialize(); } catch (LifecycleException e) { } }
接着程序会加载conf目录下的server.xml。这个文件在Tomcat的load过程中非常重要,文件的主要结构如下:
<Server port="8005" shutdown="SHUTDOWN"> <Service name="Catalina"> <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> <Engine name="Catalina" defaultHost="localhost"> <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false"/> </Engine> </Service> </Server>
看见这个文件的结构有没有一种似曾相识的感觉呢,是的,跟Tomcat的结构图如出一辙,其实这个文件的作用就是在实例化组件的时候设置相关属性的值。那么疑问就来了,上面不是组件都实例化完了吗,再读配置文件是不是迟了点。其实不是,前面讲的实例化其实只是设置实例化的规则,真正执行实例化这个操作是在digester.parse(inputSource)这一步,而读取配置文件的操作在这一步之前,因此并不会影响组件的实例化。
server.xml中的Server节点对应Server组件,其标准实现类为StandardServer类,Server节点的属性port和shutdown对应StandardServer类的port和shutdown属性,在实例化Server组件的时候,通过属性的set方法,将Server节点的属性赋值给StandardServer,并且会将五个Listener子节点通过addLifecycleListener方法添加到一个数组里。
Service节点对应Service组件,Service节点下有两类子节点,分别是Connector型和Container。其中Connector类型的节点有两个,一个支持HTTP/1.1协议,另一个支持AJP/1.3。实例化Http连接器的时候,也是通过set方法,分别设置Connector类的port和protocol等属性的值。其中port属性表示监听的端口号,Tomcat启动时报端口被占用的错误就是因为这个端口被其他程序占用了。Container类型的子节点默认有两个,Engine和Host,分别对应Engine容器和Host容器。实例化Engine的时候,设置默认host为localhost,并且设置容器的名字为Catalina。同样,实例化Host容器的时候,会分别设置appBase,unpackWARs,autoDeploy等属性的值。
在实例化组件的时候,很多属性都是有默认值的,现在我们知道了程序会使用server.xml中的值来覆盖默认值,那么如果我们想在实例化改时改变某些属性的值,就可以通过修改server.xml中的值来达到这个目的。
执行完digester.parse(inputSource)这句代码之后,Server,Service,Connector等组件将正式执行实例化操作。
那么组件都实例化完之后该执行什么操作呢?未完待续。。。。。。
相关文章推荐
- Tomcat源码阅读之Container与Pipeline的设计
- tomcat源码阅读2
- tomcat源码阅读4
- tomcat源码阅读23
- tomcat源码阅读_代码篇3
- tomcat源码阅读_代码篇2
- Tomcat源码阅读(四)之JMX在Tomcat中的应用(一)
- tomcat源码阅读_代码篇7
- tomcat源码阅读21
- tomcat源码阅读20
- tomcat源码阅读_代码篇5
- tomcat源码阅读5
- tomcat源码阅读10
- tomcat源码阅读9
- tomcat源码阅读22
- tomcat源码阅读3
- tomcat源码阅读8
- tomcat源码阅读12
- tomcat源码阅读26
- tomcat源码阅读_代码篇6