Tomcat源码分析 · 叁——init方法补充
前言
昨天剖析了Tomcat
的init
方法,整个流程看着虽然不长,但是分析起来确实挺繁琐的,所以今天要继续剖析。
实话实说,我都觉得挺拖沓的,不过暂时也没别的办法,毕竟我也正在找一个比较好的更新状态,因为持续高效输出也是我一直的追求,而且我也希望每天都能输出高价值的内容,所以如果各位老铁有好的想法或者建议,欢迎沟通交流,毕竟在这个成长进步的道路是永远不会休止的。
Tomcat
今天我们先来看下init
中反射调用的catalina
的load
和start
方法的具体实现,先看load
方法:
从这里我们可以看出来,它调用的是catalina
中有参的load
方法,参数就是main
方法的args
参数。进入load
方法之后,它先调用了arguments
方法,并根据这个方法的返回值判断是否需要执行load
方法(无参):
arguments
方法会校验args
中的参数,如果args
为空,或者非法参数,该方法返回false
,我们从前天的内容知道,这里的args
参数第一个值为start
,所以最终这个方法会返回true
。另外,这里的usage
方法是在我们输入非法参数的时候,打印具体的用法,就类似于shell
中的usage
提示:
下面我们继续看无参的load
方法,这个方法太长了,这里我们直接分段截图讲解。先看第一部分:
首先是初始化文件夹方法initDirs
,实际上这个方法并没有用,而且根据目前官方的注释,将在10
版本移除这个方法:
然后是initNaming
方法,这个方法的主要作用是设置系统的配置参数,这些参数最终会被存放在System
的props
属性中(这里的props
是一个Properties
对象):
再下来就是createStartDigester
,这个方法的作用是创建并配置xml
文件消化器,为后续解析Tomcat
的xml
配置文件做准备:
然后就是configFile
方法在,这个方法的作用是获取conf/server.xml
文件:
配置文件获取完成后,会根据获取到的配置文件构建FileInputStream
和InputSource
。
如果构建失败会再次通过getConfigFile
获取配置文件,再次构建输入流和输入资源;如果这里还是构建失败,会基于server-embed.xml
构建输入流和输入资源,如果以上操作之后还是失败,这时候会打印警告信息,然后返回:
try {
file = configFile();
inputStream = new FileInputStream(file);
inputSource = new InputSource(file.toURI().toURL().toString());
} catch (Exception e) {
if (log.isDebugEnabled()) {
log.debug(sm.getString("catalina.configFail", file), e);
}
}
if (inputStream == null) {
try {
inputStream = getClass().getClassLoader()
.getResourceAsStream(getConfigFile());
inputSource = new InputSource
(getClass().getClassLoader()
.getResource(getConfigFile()).toString());
} catch (Exception e) {
if (log.isDebugEnabled()) {
log.debug(sm.getString("catalina.configFail",
getConfigFile()), e);
}
}
}
// This should be included in catalina.jar
// Alternative: don't bother with xml, just create it manually.
if (inputStream == null) {
try {
inputStream = getClass().getClassLoader()
.getResourceAsStream("server-embed.xml");
inputSource = new InputSource
(getClass().getClassLoader()
.getResource("server-embed.xml").toString());
} catch (Exception e) {
if (log.isDebugEnabled()) {
log.debug(sm.getString("catalina.configFail",
"server-embed.xml"), e);
}
}
}
if (inputStream == null || inputSource == null) {
if (file == null) {
log.warn(sm.getString("catalina.configFail",
getConfigFile() + "] or [server-embed.xml]"));
} else {
log.warn(sm.getString("catalina.configFail",
file.getAbsolutePath()));
if (file.exists() && !file.canRead()) {
log.warn("Permissions incorrect, read permission is not allowed on the file.");
}
}
return;
}
如果输入流和输入资源都创建ok
,则会通过前面已经创建好的digester
实例进行资源解析:
接着会获取server
对象并设置它的属性:
但是有个问题,在之前的过程中我并没有发现哪里有实例化Server
,这里直接获取就不怕直接空指针嘛,所以初步推断前面有实例化Server
的操作,由于目前Tomcat
项目无法debug
运行,所以暂时还跟不了代码,这个遗留问题后面再来回过头来看。
总结
到目前为止,Tomcat
的源码还没有让我发现特别有价值的东西,所以分析这些源码其实挺无聊的,因此后面打算调整下节奏,先快速把整体流程过一下,然后找到适合分享的点再拿出来分享吧。
另外今天更新比较晚的原因是,在公司写工具分享内容,一下写了两篇,所以今天回来比较晚,也就更新晚了,不过好消息是,明天我可以把今天分享的工具内容同步分享出来,供各位小伙伴参考。
好了,今天就到这里吧,各位小伙伴晚安吧!
- END -