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

我们打开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.container!= 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启动关系类图:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值