首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

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

2012-10-20 
tomcat源码分析之Observer模式以及应用加载--Lifecycle????? 研究过tomcat源码的朋友们可能都发现了,tomca

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加载应用的流程。可谓一举两得。

?????

热点排行