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

tomcat源码研读笔记—tomcat的启动之二 StandardService的启动

2018-03-21 17:31 483 查看
我们打开standardService类,查看start方法如下:
public void start() throwsLifecycleException {
       // Validate and update our current component state
       if (started) {
           throw new LifecycleException
               (sm.getString("standardService.start.started"));
       }
       // Notify our interested LifecycleListeners
       lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);
       System.out.println
           (sm.getString("standardService.start.name", this.name));
       lifecycle.fireLifecycleEvent(START_EVENT, null);
       started = true;
       // Start our defined Container first
       if (container != null) {
           synchronized (container) {
                if (container instanceofLifecycle) {
                    ((Lifecycle)container).start();
                }
           }
       }
       // Start our defined Connectors second
       synchronized (connectors) {
           for (int i = 0; i < connectors.length; i++) {
                if (connectors[i] instanceofLifecycle)
                    ((Lifecycle)connectors[i]).start();
           }
       }
       // Notify our interested LifecycleListeners
       lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);
}
 
我们会发现,:
1,  其实这里也采用standardServer的监听者模式,同样的我们去找lifecycleListener的实现类,发现原来在server.xml是没有配置standardService监听器的,所以这里没有监听事件的执行咯
2,  根据代码我们可以知道,接下来会对container属性执行启动,然后再循环执行connectors的启动
3,  我们查看container属性可以知道:
private Container container = null
 
这里一开始初始化时一个null是无法执行的,但是我们根据属性的get和set方法,那么必定知道有个setContainer方法,如下:
publicvoid setContainer(Container container) {
 
        Container oldContainer =this.container;
        if ((oldContainer != null) &&(oldContainer instanceof Engine))
            ((Engine)oldContainer).setService(null);
        this.container = container;
        if ((this.container != null) &&(this.container instanceof Engine))
            ((Engine)this.container).setService(this);
        if (started && (this.containe
4000
r!= null) &&
            (this.container instanceofLifecycle)) {
            try {
                ((Lifecycle)this.container).start();
            } catch (LifecycleException e) {
                ;
            }
        }
        synchronized (connectors) {
            for (int i = 0; i <connectors.length; i++)
                connectors[i].setContainer(this.container);
        }
        if (started && (oldContainer !=null) &&
            (oldContainer instanceofLifecycle)) {
            try {
                ((Lifecycle)oldContainer).stop();
            } catch (LifecycleException e) {
                ;
            }
        }
  这里很简单,判断了下container是否是Engine和Lifecycle的实现类,如果是设置了下service和执行了containder的start方法,接下来还循环设置了下connectors里边connector的container这个时候,我们的疑问有来了,既然这里有这个方法,那么究竟是哪个地方调用了该方法呢?
 
4,  我们再次回想下server.xml文件结构,再次返回到Catalina类Digester设置实例的方法里边:
digester.addRuleSet(newEngineRuleSet("Server/Service/"));
 
在看看EngineRuleSet中的addRuleInstances方法:
    digester.addObjectCreate(prefix +"Engine",
                                "org.apache.catalina.core.StandardEngine",
                                "className");
        digester.addSetProperties(prefix +"Engine");
        digester.addRule(prefix +"Engine",
                         newLifecycleListenerRule
                         (digester,
                          "org.apache.catalina.startup.EngineConfig",
                         "engineConfigClass"));
        digester.addSetNext(prefix +"Engine",
                           "setContainer",
                           "org.apache.catalina.Container");
 
这个时候,我们可以知道这里调用的setContainer,给standardService设置了Container就是StandardEngine.
5,至此StandardService已经将启动操作传递给了standardEngine. 我们看看流程如下:



standardService启动关系类图:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: