tomcat源码分析之Observer模式以及应用加载--Lifecycle

      研究过tomcat源码的朋友们可能都发现了,tomcat中几个主要的component都实现了Lifecycle接口,并且在

start的时候通常都会publish一些事件。在这个过程中tomcat是通过Observer模式来实现相关功能的。下面以StandardHost为例来说明。

 

      StandardHost是StandardContext(也就是部署在tomcat下面的一个个应用)的上级Container.Host是在Digester server.xml文件的时候生成的。但是,在digester的时候,并没有standardcontext的相关配置。那么,StandardContext是如何加载的呢?

 

     下面就来研究一下standardhost的源码:

      先来看init源码:

     

 public void init() {
        if( initialized ) return;
        initialized=true;
        
        // already registered.
        if( getParent() == null ) {
            try {
                // Register with the Engine
                ObjectName serviceName=new ObjectName(domain + 
                                        ":type=Engine");

                HostConfig deployer = new HostConfig();
                addLifecycleListener(deployer);                
                if( mserver.isRegistered( serviceName )) {
                    if(log.isDebugEnabled())
                        log.debug("Registering "+ serviceName +" with the Engine");
                    mserver.invoke( serviceName, "addChild",
                            new Object[] { this },
                            new String[] { "org.apache.catalina.Container" } );
                }
            } catch( Exception ex ) {
                log.error("Host registering failed!",ex);
            }
        }
        
        if( oname==null ) {
            // not registered in JMX yet - standalone mode
            try {
                StandardEngine engine=(StandardEngine)parent;
                domain=engine.getName();
                if(log.isDebugEnabled())
                    log.debug( "Register host " + getName() + " with domain "+ domain );
                oname=new ObjectName(domain + ":type=Host,host=" +
                        this.getName());
                controller = oname;
                Registry.getRegistry(null, null)
                    .registerComponent(this, oname, null);
            } catch( Throwable t ) {
                log.error("Host registering failed!", t );
            }
        }
    }

 

     

    StandardHost本身是一个container(ContainerBase),从以上代码可以看出,它在初始化的时候注册了一个LifecycleListener:HostConfig. 不同于一般的Observer模式的地方是,standard并不直接拥有listeners,而是通过拥有一个工具类-LifecycleSupport来维护与listeners的关系。这样就使得代码看起来很干净。已经注册了Observer,那么在哪里触发事件呢?事件触发是在container启动的时候(其实观察tomcat6中的重要组件,比如standardserver,standardservice以及container如standardengine,standardhost,standardcontext,他们在start的时候都会发布这么几个事件:beforestartevent,startevent,afterstartevent). 于是在standardhost start的时候,触发事件,listeners作出响应,hostconfig的响应代码如下:

 

   

public void lifecycleEvent(LifecycleEvent event) {

        if (event.getType().equals(Lifecycle.PERIODIC_EVENT))
            check();

        // Identify the host we are associated with
        try {
            host = (Host) event.getLifecycle();
            if (host instanceof StandardHost) {
                setDeployXML(((StandardHost) host).isDeployXML());
                setUnpackWARs(((StandardHost) host).isUnpackWARs());
                setXmlNamespaceAware(((StandardHost) host).getXmlNamespaceAware());
                setXmlValidation(((StandardHost) host).getXmlValidation());
            }
        } catch (ClassCastException e) {
            log.error(sm.getString("hostConfig.cce", event.getLifecycle()), e);
            return;
        }

        // Process the event that has occurred
        if (event.getType().equals(Lifecycle.START_EVENT))
            start();
        else if (event.getType().equals(Lifecycle.STOP_EVENT))
            stop();

    }

 

    可以看出,如果触发的事件是START_EVENT,那么hostconfig调用自己的start方法。而正是在

    start方法里面,调用deployApps来生成standardContext.

     至此,不仅了解了tomcat中Lifecycle的Observer模式,而且了解了tomcat加载应用的流程。可谓一举两得。

     

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值