当前位置:首页 > 开发 > 编程语言 > Java > 正文

tomcat生命周期管理 LifeCycle

发表于: 2010-05-17   作者:splinter_2   来源:转载   浏览次数:
摘要: Servlet规范中定义了一个Servlet的生命周期,Tomcat使用事件方式管理Servlet的生命周期。Tomcat定义了一个Lifecycle接口统一管理在容器内发生的所有事件。Lifecycle接定义了两个方法start,stop来完成创建,初始化和结束的生命周期管理。Lifecycle接口一共定义了九种事件类型。所有容器内处理Servlet的类都继承该接口,如StandarServer

Servlet规范中定义了一个Servlet的生命周期, Tomcat使用事件方式管理Servlet的生命周期。 Tomcat定义了一个Lifecycle接口统一管理在容器内发生的所有事件。


Lifecycle接定义了两个方法start, stop来完成创建,初始化和结束的生命周期管理。

Lifecycle接口一共定义了九种事件类型。 所有容器内处理Servlet的类都继承该接口, 如StandarServer, StandarPipeline,ContainerBase以及各种Valve。

本文主要分析Tomcat中声明周期管理的设计和实现。

Author: Benewu(at)gmail.com

一,设计: Tomcat使用了组合(Composite)和观察者(Observer)模式。

设计核心是: Lifecycle, LifecycleListener, LifecycleEvent和LifecycleSupport



Lifecycle组合了LifecycleSupport,

1. 注册事件: Lifecycle中定义的addLifecycleListener实际是使用LifecycleSupport的addLifecycleListener。

2. 通知监听者: 当Lifecycle中发生动作尤其是start和stop时会调用LifecycleSupport的fireLifecycleEvent。 这个时候LifecycleSupport的fireLifecycleEvent会根据传入的事件类型,生成LifecycleEvent事件源并且遍历通知所有注册在里面的监听(LifecycleListener)的lifecycleEvent方法.

3. 监听者响应: 监听(LifecycleListener)会根据不同的事件类型做不同的操作。


二, 实现:

   以JasperListener(初始化JSP编译引擎)监听在StandarServer的注册,通知和响应为例。

1. 注册事件: Tomcat允许用户自定义监听和加入,可以在serer.xml中灵活的配置。

Java代码 复制代码
  1. <Server port="8005" shutdown="SHUTDOWN">   
  2.   
  3.   ... ...   
  4.   <!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html -->   
  5.   <Listener className="org.apache.catalina.core.JasperListener" />   
  6.   
  7.   ... ...   
  8.   
  9. </Server>  
<Server port="8005" shutdown="SHUTDOWN">

  ... ...
  <!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html -->
  <Listener className="org.apache.catalina.core.JasperListener" />

  ... ...

</Server>



StandardServer继承Lifecycle接口, 有注册监听的方法。
StandardServer中注册监听的代码片断:
org.apache.catalina.core.StandardServer

Java代码 复制代码
  1. public final class StandardServer   
  2.     implements Lifecycle, Server, MBeanRegistration    
  3.  {   
  4.   
  5.   ... ...   
  6.   
  7.     // 组合模式   
  8.     private LifecycleSupport lifecycle = new LifecycleSupport(this);   
  9.   
  10.   ... ...   
  11.   
  12.     // 将监听加入到模块中   
  13.     public void addLifecycleListener(LifecycleListener listener) {   
  14.   
  15.         lifecycle.addLifecycleListener(listener);   
  16.   
  17.     }   
  18.   ... ...   
  19.   
  20. }  
public final class StandardServer
    implements Lifecycle, Server, MBeanRegistration 
 {

  ... ...

    // 组合模式
    private LifecycleSupport lifecycle = new LifecycleSupport(this);

  ... ...

    // 将监听加入到模块中
    public void addLifecycleListener(LifecycleListener listener) {

        lifecycle.addLifecycleListener(listener);

    }
  ... ...

}




org.apache.catalina.util.LifecycleSupport 中addLifecycleListener方法完成注册监听的具体实现:

Java代码 复制代码
  1. public final class LifecycleSupport {   
  2.   ... ...   
  3.     private LifecycleListener listeners[] = new LifecycleListener[0];   
  4.   
  5.   ... ...   
  6.     public void addLifecycleListener(LifecycleListener listener) {   
  7.   
  8.       synchronized (listeners) {   
  9.           LifecycleListener results[] =   
  10.             new LifecycleListener[listeners.length + 1];   
  11.           for (int i = 0; i < listeners.length; i++)   
  12.               results[i] = listeners[i];   
  13.           results[listeners.length] = listener;   
  14.           listeners = results;   
  15.       }   
  16.   
  17.     }   
  18.   ... ...   
  19. }  
public final class LifecycleSupport {
  ... ...
    private LifecycleListener listeners[] = new LifecycleListener[0];

  ... ...
    public void addLifecycleListener(LifecycleListener listener) {

      synchronized (listeners) {
          LifecycleListener results[] =
            new LifecycleListener[listeners.length + 1];
          for (int i = 0; i < listeners.length; i++)
              results[i] = listeners[i];
          results[listeners.length] = listener;
          listeners = results;
      }

    }
  ... ...
}



Tomcat在启动的时候会将xml中配置的内容加载进去,(见《Tomcat中xml的解析器Digester》), 完成监听注册。


2. 通知监听者。

StandardServer在自身初始化的时候通知所有监听有初始化事件发生。

Java代码 复制代码
  1.    public void initialize()   
  2.         throws LifecycleException    
  3.     {   
  4.         if (initialized) {   
  5.                 log.info(sm.getString("standardServer.initialize.initialized"));   
  6.             return;   
  7.         }   
  8.         lifecycle.fireLifecycleEvent(INIT_EVENT, null);   
  9.         initialized = true;   
  10.   ... ...   
  11. }  
   public void initialize()
        throws LifecycleException 
    {
        if (initialized) {
                log.info(sm.getString("standardServer.initialize.initialized"));
            return;
        }
        lifecycle.fireLifecycleEvent(INIT_EVENT, null);
        initialized = true;
  ... ...
}



LifecycleSupport实现具体动作, 生成事件源并通知所有监听

Java代码 复制代码
  1. public void fireLifecycleEvent(String type, Object data) {   
  2.   
  3.     LifecycleEvent event = new LifecycleEvent(lifecycle, type, data);   
  4.     LifecycleListener interested[] = listeners;   
  5.     for (int i = 0; i < interested.length; i++)   
  6.         interested[i].lifecycleEvent(event);   
  7.   
  8. }  
    public void fireLifecycleEvent(String type, Object data) {

        LifecycleEvent event = new LifecycleEvent(lifecycle, type, data);
        LifecycleListener interested[] = listeners;
        for (int i = 0; i < interested.length; i++)
            interested[i].lifecycleEvent(event);

    }



3. 监听者响应

当LifecycleListener被调用lifecycleEvent方法, 会分析事件的类型, 根据类型做不同的响应或者不响应。

org.apache.catalina.core.JasperListener被注册在StandardServer,当StandardServer通知事件的时候, 它也会被调用。
调用到底方法是: lifecycleEvent

Java代码 复制代码
  1. public class JasperListener   
  2.     implements LifecycleListener {   
  3.   ... ...   
  4.     public void lifecycleEvent(LifecycleEvent event) {   
  5.         // 判断事件类型, 根据类型作出响应   
  6.         if (Lifecycle.INIT_EVENT.equals(event.getType())) {   
  7.             try {   
  8.                 // Set JSP factory   
  9.                 Class.forName("org.apache.jasper.compiler.JspRuntimeContext",   
  10.                               true,   
  11.                               this.getClass().getClassLoader());   
  12.             } catch (Throwable t) {   
  13.                 // Should not occur, obviously   
  14.                 log.warn("Couldn't initialize Jasper", t);   
  15.             }   
  16.             // Another possibility is to do directly:   
  17.             // JspFactory.setDefaultFactory(new JspFactoryImpl());   
  18.         }   
  19.   
  20.     }   
  21.   
  22.    ... ...   
  23. }  
public class JasperListener
    implements LifecycleListener {
  ... ...
    public void lifecycleEvent(LifecycleEvent event) {
        // 判断事件类型, 根据类型作出响应
        if (Lifecycle.INIT_EVENT.equals(event.getType())) {
            try {
                // Set JSP factory
                Class.forName("org.apache.jasper.compiler.JspRuntimeContext",
                              true,
                              this.getClass().getClassLoader());
            } catch (Throwable t) {
                // Should not occur, obviously
                log.warn("Couldn't initialize Jasper", t);
            }
            // Another possibility is to do directly:
            // JspFactory.setDefaultFactory(new JspFactoryImpl());
        }

    }

   ... ...
}



   至此, Tomcat的生命周期管理分析就完成了。 可以看出Tomcat的生命周期管理设计的非常灵活和简单, 用户可以自如的加入不同监听到各个环节。

   但也看出这个设计也有一些缺点, 比如每个监听都会被通知一遍,然后自己去判断事件类型。 如果容器发生的事件多而且监听也多, 会造成很多不必要的损耗。当然Tomcat的这个问题不是很大, 因为Tomcat发生的事件不多而且监听也不是很多。


参考:
1 Java Servlet概述
http://tech.ccidnet.com/art/1077/20041123/180515_1.html

Java代码 复制代码
  1.   
 



2 Tomcat 6官方文档
http://tomcat.apache.org/tomcat-6.0-doc/index.html

tomcat生命周期管理 LifeCycle

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
一,tomcat中每一个容器都有其生命周期,初始化/启动/结束 等,可以在各自的生命周期内的步骤中进行
Tomcat 包含多个很多个组件, Tomcat 内部使用一个观察者模式来组织这些组件之间的关系,做到同时启
Maven生命周期Lifecycle Maven有三类生命周期 The following lists all build phases of the defaul
Android中的生命周期LifeCycle 一、场景 Activity从新建到销毁,构成了一个生命周期。当然生命周期
经常在框架里面看到LifeCycle,但是不知道通过这个LifeCycle抽象,一个复杂应用到底是如何将构成自身
(product lifecycle management)产品生命周期管理 根据业界权威的CIMDATA的定义,PLM是一种应用于在
本文主要结合观察者模式,讲述Tomcat的生命周期管理。Tomcat的生命周期管理机制设计的非常优雅,在T
本文主要结合观察者模式,讲述Tomcat的生命周期管理。Tomcat的生命周期管理机制设计的非常优雅,在T
在上篇文章分析Tomcat7的各组件的init、start方法时经常会看到有一个setStateInternal方法的调用,
这其实并不是一个复杂的问题,但是似乎没有什么资料对此做过清晰的说明,本文将对这个问题做一个详
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号