zoukankan      html  css  js  c++  java
  • Tomcat学习笔记(五)

      生命周期事件

      Catalina包含有很多组件。当Catalina启动时,这些组件也会启动,同样,当Catalina关闭时,这些组件也随之关闭,通过实现org.apache.catalina.Lifecycle接口,可以达到统一启动/关闭这些组件的效果。

       实现Lifecycle接口的组件可以触发一个或多个下面的事件:BEFORE_START_EVENT、START_EVENT、AFTER_START_EVENT、BEFORE_STOP_EVENT、STOP_EVENT、AFTER_STOP_EVENT 。当组件启动时,正常会触发前3个事件,而关闭组件时,会触发后3个事件。如果Catalina组件可以触发事件,那么需要编写相应的事件监听器对这些事件进行响应。事件监听器是org.apache.catalina.LifecycleListener接口实例。

       tomcat内部架构各个核心组件的包含关系。例如server包含service,service包含container,一层层包含。而这种结构类似数据结构中的树形结构,对于tomcat的启动也是鉴于此,可以通过父容器启动子容器,这样可以达到只要启动根容器,从而启动所有的组件,同时便于管理达到统一启动、停止、关闭的效果。

                                                               

          生命周期采用是观察者模式(监听事件)。

                                                         

    简单看一下tomcat的设计源码

    事件对象LifecycleEvent

    public final class LifecycleEvent extends EventObject {
    
        private static final long serialVersionUID = 1L;
    
    
        // ----------------------------------------------------------- Constructors
    
        /**
         * Construct a new LifecycleEvent with the specified parameters.
         *
         * @param lifecycle Component on which this event occurred
         * @param type Event type (required)
         * @param data Event data (if any)
         */
        public LifecycleEvent(Lifecycle lifecycle, String type, Object data) {
    
            super(lifecycle);
            this.type = type;
            this.data = data;
        }
    
    
        // ----------------------------------------------------- Instance Variables
    
    
        /**
         * The event data associated with this event.
         */
        private Object data = null;
    
    
        /**
         * The event type this instance represents.
         */
        private String type = null;
    
    
        // ------------------------------------------------------------- Properties
    
    
        /**
         * Return the event data of this event.
         */
        public Object getData() {
    
            return (this.data);
    
        }
    
    
        /**
         * Return the Lifecycle on which this event occurred.
         */
        public Lifecycle getLifecycle() {
    
            return (Lifecycle) getSource();
    
        }
    
        /**
         * Return the event type of this event.
         */
        public String getType() {
    
            return (this.type);
    
        }
    
    }

    事件监听接口LifecycleListener

    public interface LifecycleListener {
    
    
        /**
         * Acknowledge the occurrence of the specified event.
         *
         * @param event LifecycleEvent that has occurred
         */
        public void lifecycleEvent(LifecycleEvent event);
    
    
    }

    事件监听实现类JasperListener

    public void lifecycleEvent(LifecycleEvent event) {
    
            if (Lifecycle.BEFORE_INIT_EVENT.equals(event.getType())) {
                try {
                    // Set JSP factory
                    Class.forName("org.apache.jasper.compiler.JspRuntimeContext",
                                  true,
                                  this.getClass().getClassLoader());
                } catch (Throwable t) {
                    ExceptionUtils.handleThrowable(t);
                    // Should not occur, obviously
                    log.warn("Couldn't initialize Jasper", t);
                }
                // Another possibility is to do directly:
                // JspFactory.setDefaultFactory(new JspFactoryImpl());
            }
    
        }

    事件监听类LifecycleSupport

    public void addLifecycleListener(LifecycleListener listener) {
    
          synchronized (listenersLock) {
              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;
          }
    
        }
    //触发事件
    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);
    
        }
    //移除事件
    public void removeLifecycleListener(LifecycleListener listener) {
    
            synchronized (listenersLock) {
                int n = -1;
                for (int i = 0; i < listeners.length; i++) {
                    if (listeners[i] == listener) {
                        n = i;
                        break;
                    }
                }
                if (n < 0)
                    return;
                LifecycleListener results[] =
                  new LifecycleListener[listeners.length - 1];
                int j = 0;
                for (int i = 0; i < listeners.length; i++) {
                    if (i != n)
                        results[j++] = listeners[i];
                }
                listeners = results;
            }
    
        }

           事件源 ServerStandard@startInternal()

    //触发事件
    protected void startInternal() throws LifecycleException {
    
            fireLifecycleEvent(CONFIGURE_START_EVENT, null);
            setState(LifecycleState.STARTING);
    
            globalNamingResources.start();
            
            // Start our defined Services
            synchronized (services) {
                for (int i = 0; i < services.length; i++) {
                    services[i].start();
                }
            }
        }

    下面写了一个简单观察者模式的例子,便于理解。

    import java.util.ArrayList;
    import java.util.List;
    
    class MacBookPro{
        
        public List<ITClient> clients = new ArrayList<ITClient>();
    
        public void addClientListener(ITClient client){
            clients.add(client);
        }
        public void notifyClient(String info){
            //通知所有放入监听者
            clients.forEach(x->x.receiveInfo(info));
        }
    }
    class ITClient{
        
        private String name;
        
        public ITClient(String name)
        {
            this.name = name;
        }
        public void receiveInfo(String info){
            System.out.println(this.name+" :: "+info);
        }
    }
    public class StateTest
    {
        public static void main(String[] args)
        {
            MacBookPro mbp = new MacBookPro();
            ITClient c1 = new ITClient("员工1");
            ITClient c2 = new ITClient("员工2");
            ITClient c3 = new ITClient("员工3");
            mbp.addClientListener(c1);
            mbp.addClientListener(c2);
            mbp.addClientListener(c3);
            System.out.println("促销活动开始了");
            mbp.notifyClient("京东618大减价");
        }
    }

    结果:

    促销活动开始了
    员工1 :: 京东618大减价
    员工2 :: 京东618大减价
    员工3 :: 京东618大减价
  • 相关阅读:
    hdu 1704 Rank(floyd传递闭包)
    codeforces 85D. Sum of Medians(线段树or分块)
    hdu 1706 The diameter of graph(folyd计数)
    hdu 4705 Y(树形DP)
    hdu 4123 Bob’s Race(树形DP+rmq)
    hdu 2196 Computer(树形DP)
    hdu 3534 Tree(树形DP)
    hdu 6017 Girls Love 233(dp)
    [HDU5903]Square Distance(DP)
    HDU5878~HDU5891 2016网络赛青岛
  • 原文地址:https://www.cnblogs.com/lzeffort/p/7050920.html
Copyright © 2011-2022 走看看