您的位置:首页 > 运维架构 > Tomcat

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。这几个容器实例化过程都比较简单,基本都是设置下基础阀。关于阀的内容在阅读容器处理请求流程部分会详细讲解。

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等组件将正式执行实例化操作。

那么组件都实例化完之后该执行什么操作呢?未完待续。。。。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: