码迷,mamicode.com
首页 > 其他好文 > 详细

tomcat启动过程分析

时间:2014-08-04 20:46:58      阅读:214      评论:0      收藏:0      [点我收藏+]

标签:使用   os   io   文件   for   art   问题   ar   

1、通过catalina.sh start脚本启动,调用org.apache.catalina.startup.Bootstrap的main方法,传人参数start,首先是创建一个Bootstrap的实例并付给static变量daemon,然后调用daemon的init方法,在init方法中设置catalina-home,catalina-base,之后根据catalina.properties的配置创建commonLoader(父loader为空)、catalinaLoader、sharedLoader(server.loader,shared.loader默认为空,此时,catalinaLoader、sharedLoader使用其父loader即commonLoader),将catalinaLoader设为当前线程的上下文classloader,如果设置了SecurityManager,则preload一些class文件,然后调用catalinaLoader加载org.apache.catalina.startup.Catalina,并初始化一个实例startupInstance,赋值给catalinaDaemon,通过反射调用startupInstance的setParentClassLoader方法,将ParentClassLoader设置为sharedLoader。然后调用daemon的load方法,通过反射调用catalinaDaemon的load方法。最后调用daemon的start方法,通过反射调用catalinaDaemon的start方法。
 
2、catalina的load方法
首先初始化catalina-home等dir,初始化naming,然后创建digester,用来读取conf/server.xml配置文件,创建server、service等组件。

initDirs();

// Before digester - it may be needed

initNaming();

// Create and execute our Digester
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) {
  ;
}

tomcat初始化组件server、service、engine、host、context等,并设置包含关系的过程是通过开源的digester库来完成的,根据配置文件conf/server.xml中配置的信息来初始化各个组件,而不是通过硬编码的方式(配置有改动之后需要重新编译),提供了极大的灵活性。
在调用digester的parse方法处理xml之前,需要制定一系列的规则,例如遇到server、service元素时需要采取什么动作,做哪些关联等。例如:
 
digester.addObjectCreate("Server", "org.apache.catalina.core.StandardServer",  "className"); 
digester.addSetProperties("Server");
digester.addSetNext("Server", "setServer", "org.apache.catalina.Server");
 
上面的三条规则的第一个参数都是patten,即指定遇到这个server标签时采取的动作:
第一条当遇到Server标签时,创建一个server对象,如果没有制定className属性的话,则默认创建org.apache.catalina.core.StandardServer类的实例,否则根据制定的className属性来创建server,并压人digester的栈中;
第二条addSetProperties将digester的栈顶元素(即刚压人的server实例)出栈,并根据xml中配置的属性调用相应方法给server实例进行设置;
第三条addSetNext将栈顶的2个元素出栈,假设第一个出栈为a,第二个为b,则调用b的setServer方法,参数是a,而且a的Type为org.apache.catalina.Server。
这里有个问题,Server是server.xml的顶层标签,当遇到第一条规则的时候只向栈里压了一个元素,第三条规则要求出栈2个元素,栈底是哪个元素?
在load方法创建digester之后,调用parse之前,还压人了一个元素,代码如下:
 
digester.push(this);
digester.parse(inputSource);
 
即把Catalina实例本身压人栈中,Catalina继承了Embedded,Embedded又继承了StandardService,看见Catalina是一个service,这样就把Catalina的server变量指向了堆栈中的server实例。
由于server和service是一对多的关系,通过server.xml可以配置server标签包含service标签,即server指向service,而反向关系需要通过上述规则进行设置。
 
3、catalina的start方法
        // Start the new server
        if (getServer() instanceof Lifecycle) {
            try {
                ((Lifecycle) getServer()).start();
            } catch (LifecycleException e) {
                log.error("Catalina.start: ", e);
            }
        }
getServer即第2步中通过第三条获得的Server实例,调用其start方法,将依次调用其组件的start方法。
 
之后设置退出钩子,当用户关闭tomcat窗口或者杀死进程时,启动CatalinaShutdownHook线程,调用stop方法。
        if (shutdownHook == null) {
                shutdownHook = new CatalinaShutdownHook();
        }
        Runtime.getRuntime().addShutdownHook(shutdownHook);
 
然后主线程进入等待状态,监听8005端口,如果收到“SHUTDOWN”命令则退出。
 

tomcat启动过程分析,布布扣,bubuko.com

tomcat启动过程分析

标签:使用   os   io   文件   for   art   问题   ar   

原文地址:http://www.cnblogs.com/7mile/p/3890721.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!