Tomcat中的观察者模式 (Lifecycle)

几个重要的类,接口

LifeCycle : 主题接口

LifeCycleBase : 抽象的主题实现

LifeCycleListener : 观察者

具体分析


public interface Lifecycle {   //主题接口

    // ----------------------------------------------------- Manifest Constants

    /**
     * The LifecycleEvent type for the "component before init" event.

     */
    public static final String BEFORE_INIT_EVENT = "before_init";   //定义了tomcat启动时的状态

    /**
     * The LifecycleEvent type for the "component after init" event.

     */
    public static final String AFTER_INIT_EVENT = "after_init";

    /**
     * The LifecycleEvent type for the "component start" event.

     */
    public static final String START_EVENT = "start";

    /**
     * The LifecycleEvent type for the "component before start" event.

     */
    public static final String BEFORE_START_EVENT = "before_start";

    /**
     * The LifecycleEvent type for the "component after start" event.

     */
    public static final String AFTER_START_EVENT = "after_start";

    /**
     * The LifecycleEvent type for the "component stop" event.

     */
    public static final String STOP_EVENT = "stop";

    /**
     * The LifecycleEvent type for the "component before stop" event.

     */
    public static final String BEFORE_STOP_EVENT = "before_stop";

    /**
     * The LifecycleEvent type for the "component after stop" event.

     */
    public static final String AFTER_STOP_EVENT = "after_stop";

    /**
     * The LifecycleEvent type for the "component after destroy" event.

     */
    public static final String AFTER_DESTROY_EVENT = "after_destroy";

    /**
     * The LifecycleEvent type for the "component before destroy" event.

     */
    public static final String BEFORE_DESTROY_EVENT = "before_destroy";

    /**
     * The LifecycleEvent type for the "periodic" event.

     */
    public static final String PERIODIC_EVENT = "periodic";

    /**
     * The LifecycleEvent type for the "configure_start" event. Used by those
     * components that use a separate component to perform configuration and
     * need to signal when configuration should be performed - usually after
     * {@link #BEFORE_START_EVENT} and before {@link #START_EVENT}.

     */
    public static final String CONFIGURE_START_EVENT = "configure_start";

    /**
     * The LifecycleEvent type for the "configure_stop" event. Used by those
     * components that use a separate component to perform configuration and
     * need to signal when de-configuration should be performed - usually after
     * {@link #STOP_EVENT} and before {@link #AFTER_STOP_EVENT}.

     */
    public static final String CONFIGURE_STOP_EVENT = "configure_stop";

    // --------------------------------------------------------- Public Methods

    /**
     * Add a LifecycleEvent listener to this component.

     *
     * @param listener The listener to add
     */
    public void addLifecycleListener(LifecycleListener listener);     //注册观察者的方法

    /**
     * Get the life cycle listeners associated with this life cycle.

     *
     * @return An array containing the life cycle listeners associated with this
     *         life cycle. If this component has no listeners registered, a
     *         zero-length array is returned.

     */
    public LifecycleListener[] findLifecycleListeners();              //获得所有的观察者的方法

    /**
     * Remove a LifecycleEvent listener from this component.

     *
     * @param listener The listener to remove
     */
    public void removeLifecycleListener(LifecycleListener listener);    //移除观察者的方法

    /**
     * Prepare the component for starting. This method should perform any
     * initialization required post object creation. The following
     * {@link LifecycleEvent}s will be fired in the following order:
     * <ol>
     *   <li>INIT_EVENT: On the successful completion of component
     *                   initialization.</li>
     * </ol>
     *
     * @exception LifecycleException if this component detects a fatal error
     *  that prevents this component from being used
     */
    public void init() throws LifecycleException;             //&#x521D;&#x59CB;&#x5316;&#x5BB9;&#x5668;&#x7684;&#x65B9;&#x6CD5;

    /**
     * Prepare for the beginning of active use of the public methods other than
     * property getters/setters and life cycle methods of this component. This
     * method should be called before any of the public methods other than
     * property getters/setters and life cycle methods of this component are
     * utilized. The following {@link LifecycleEvent}s will be fired in the
     * following order:
     * <ol>
     *   <li>BEFORE_START_EVENT: At the beginning of the method. It is as this
     *                           point the state transitions to
     *                           {@link LifecycleState#STARTING_PREP}.</li>
     *   <li>START_EVENT: During the method once it is safe to call start() for
     *                    any child components. It is at this point that the
     *                    state transitions to {@link LifecycleState#STARTING}
     *                    and that the public methods other than property
     *                    getters/setters and life cycle methods may be
     *                    used.</li>
     *   <li>AFTER_START_EVENT: At the end of the method, immediately before it
     *                          returns. It is at this point that the state
     *                          transitions to {@link LifecycleState#STARTED}.

     *                          </li>
     * </ol>
     *
     * @exception LifecycleException if this component detects a fatal error
     *  that prevents this component from being used
     */
    public void start() throws LifecycleException;     //&#x542F;&#x52A8;&#x5BB9;&#x5668;&#x7684;&#x65B9;&#x6CD5;

    /**
     * Gracefully terminate the active use of the public methods other than
     * property getters/setters and life cycle methods of this component. Once
     * the STOP_EVENT is fired, the public methods other than property
     * getters/setters and life cycle methods should not be used. The following
     * {@link LifecycleEvent}s will be fired in the following order:
     * <ol>
     *   <li>BEFORE_STOP_EVENT: At the beginning of the method. It is at this
     *                          point that the state transitions to
     *                          {@link LifecycleState#STOPPING_PREP}.</li>
     *   <li>STOP_EVENT: During the method once it is safe to call stop() for
     *                   any child components. It is at this point that the
     *                   state transitions to {@link LifecycleState#STOPPING}
     *                   and that the public methods other than property
     *                   getters/setters and life cycle methods may no longer be
     *                   used.</li>
     *   <li>AFTER_STOP_EVENT: At the end of the method, immediately before it
     *                         returns. It is at this point that the state
     *                         transitions to {@link LifecycleState#STOPPED}.

     *                         </li>
     * </ol>
     *
     * Note that if transitioning from {@link LifecycleState#FAILED} then the
     * three events above will be fired but the component will transition
     * directly from {@link LifecycleState#FAILED} to
     * {@link LifecycleState#STOPPING}, bypassing
     * {@link LifecycleState#STOPPING_PREP}
     *
     * @exception LifecycleException if this component detects a fatal error
     *  that needs to be reported
     */
    public void stop() throws LifecycleException;    //&#x5173;&#x95ED;&#x5BB9;&#x5668;&#x7684;&#x65B9;&#x6CD5;

    /**
     * Prepare to discard the object. The following {@link LifecycleEvent}s will
     * be fired in the following order:
     * <ol>
     *   <li>DESTROY_EVENT: On the successful completion of component
     *                      destruction.</li>
     * </ol>
     *
     * @exception LifecycleException if this component detects a fatal error
     *  that prevents this component from being used
     */
    public void destroy() throws LifecycleException;

    /**
     * Obtain the current state of the source component.

     *
     * @return The current state of the source component.

     */
    public LifecycleState getState();     //&#x83B7;&#x53D6;&#x5BB9;&#x5668;&#x5F53;&#x524D;&#x6240;&#x5904;&#x7684;&#x72B6;&#x6001;

    /**
     * Obtain a textual representation of the current component state. Useful
     * for JMX. The format of this string may vary between point releases and
     * should not be relied upon to determine component state. To determine
     * component state, use {@link #getState()}.

     *
     * @return The name of the current component state.

     */
    public String getStateName();

    /**
     * Marker interface used to indicate that the instance should only be used
     * once. Calling {@link #stop()} on an instance that supports this interface
     * will automatically call {@link #destroy()} after {@link #stop()}
     * completes.

     */
    public interface SingleUse {
    }
}


public abstract class LifecycleBase implements Lifecycle {   //&#x4E3B;&#x9898;&#x7684;&#x62BD;&#x8C61;&#x5B9E;&#x73B0;

    private static final Log log = LogFactory.getLog(LifecycleBase.class);

    private static final StringManager sm = StringManager.getManager(LifecycleBase.class);

    /**
     * The list of registered LifecycleListeners for event notifications.

     */
    private final List<lifecyclelistener> lifecycleListeners = new CopyOnWriteArrayList<>();   //&#x7528;&#x6765;&#x5B58;&#x50A8;&#x6240;&#x6709;&#x6CE8;&#x518C;&#x7684;&#x89C2;&#x5BDF;&#x8005;

    /**
     * The current state of the source component.

     */
    private volatile LifecycleState state = LifecycleState.NEW;

    /**
     * {@inheritDoc}
     */
    @Override
    public void addLifecycleListener(LifecycleListener listener) {    //&#x6CE8;&#x518C;&#x89C2;&#x5BDF;&#x8005;&#xFF0C;&#x5C06;&#x89C2;&#x5BDF;&#x8005;&#x6DFB;&#x52A0;&#x5230;&#x6570;&#x7EC4;&#x4E2D;
        lifecycleListeners.add(listener);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public LifecycleListener[] findLifecycleListeners() {         //&#x8FD4;&#x56DE;&#x89C2;&#x5BDF;&#x8005;&#x6570;&#x7EC4;
        return lifecycleListeners.toArray(new LifecycleListener[0]);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void removeLifecycleListener(LifecycleListener listener) { //&#x79FB;&#x9664;&#x89C2;&#x5BDF;&#x8005;&#x7684;&#x5B9E;&#x73B0;
        lifecycleListeners.remove(listener);
    }

    /**
     * Allow sub classes to fire {@link Lifecycle} events.

     *
     * @param type  Event type
     * @param data  Data associated with event.

     */
    protected void fireLifecycleEvent(String type, Object data) {   //&#x53D1;&#x5E03;&#x901A;&#x77E5;&#x7684;&#x65B9;&#x6CD5;
        LifecycleEvent event = new LifecycleEvent(this, type, data);  //&#x5C06;&#x4FE1;&#x606F;&#x5C01;&#x88C5;&#x6210;&#x4E00;&#x4E2A;LifecycleEvent&#x7C7B;&#x578B;&#x7684;&#x5BF9;&#x8C61;&#xFF0C;LifecycleEvent&#x5BF9;&#x8C61;&#x7528;&#x6765;&#x7EDF;&#x4E00;&#x5C01;&#x88C5;&#x6240;&#x6709;&#x7684;&#x4FE1;&#x606F;&#x3002;
        for (LifecycleListener listener : lifecycleListeners) {      //&#x904D;&#x5386;&#x6240;&#x6709;&#x7684;&#x89C2;&#x5BDF;&#x8005;&#xFF0C;&#x5E76;&#x53D1;&#x5E03;&#x901A;&#x77E5;
            listener.lifecycleEvent(event);
        }
    }

}
</lifecyclelistener>
public interface LifecycleListener {  //&#x89C2;&#x5BDF;&#x8005;&#x63A5;&#x53E3;

    /**
     * Acknowledge the occurrence of the specified event.

     *
     * @param event LifecycleEvent that has occurred
     */
    public void lifecycleEvent(LifecycleEvent event);  //&#x63A5;&#x53D7;&#x901A;&#x77E5;&#x7684;&#x65B9;&#x6CD5;

}

可见 tomcat中通过观察者模式来对容器的生命周期进行控制

Original: https://www.cnblogs.com/liwangcai/p/11652759.html
Author: 神奇海螺。
Title: Tomcat中的观察者模式 (Lifecycle)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/574178/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • windows 2003 不同网段 无法 文件共享 VSS设置

    网上搜索了很多解答,比如设置VPN, 修改ETC表, 自己也设置了VPN,确实可以,设置的过程需要关闭WINDOWS自带的防火墙,让我觉得不太习惯。 就研究了下防火墙的例外项 点击…

    Java 2023年6月14日
    075
  • Spring Cloud Eureka 使用 IP 地址进行服务注册

    默认情况下,Eureka 使用 hostname 进行服务注册,以及服务信息的显示,那如果我们使用 IP 地址的方式,该如何配置呢? 答案就是 eureka.instance.pr…

    Java 2023年5月30日
    084
  • 面试常问:HTTP 1.0 和 HTTP 1.1 有什么区别?

    这篇文章会从下面几个维度来对比 HTTP 1.0 和 HTTP 1.1: 响应状态码 缓存处理 连接方式 Host头处理 带宽优化 响应状态码 HTTP/1.0仅定义了16种状态码…

    Java 2023年6月9日
    066
  • 题目: 给定一个数组,添加元素(优化)

    package com.gao.test; import java.util.Scanner; /* 题目: 给定一个数组,在数组下标为2的位置上添加一个元素 */ public …

    Java 2023年6月5日
    063
  • 用浏览器连接服务器-安装新的虚拟机

    (1)在浏览器上输入https://10.100.0.249/ – 登录 (2)选中”虚拟机”,右键选择”创建/注册虚拟机&#822…

    Java 2023年5月30日
    085
  • 20220930-Vector集合扩容机制源码分析

    总结: ArrayList与Vector集合的底层都是通过Object[] elementData数组存放对象的 ArrayList使用无参构造器时,初始容量为0,当存放一个对象后…

    Java 2023年6月15日
    085
  • MySQL中OPTIMIZE TABLE和慢查询分析

    先来看看手册中关于 OPTIMIZE 的描述: OPTIMIZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name [, tbl_name] …

    Java 2023年6月9日
    056
  • 线程并发笔记(一)

    三个概念 1、可见性;2、有序性;3、原子性; 一、可见性 并发问题都是程序在不合适的时间读取了不该读取的数据,所以想要透彻弄明白并发实质还是需要看计算机的数据如何存储。计算的存储…

    Java 2023年6月7日
    090
  • nginx配置返回文本或json

    有些时候请求某些接口的时候需要返回指定的文本字符串或者json字符串,如果逻辑非常简单或者干脆是固定的字符串,那么可以使用nginx快速实现,这样就不用编写程序响应请求了,可以减少…

    Java 2023年5月30日
    080
  • 创建线程有几种方式?

    创建线程的几种方式 1️⃣ 继承 Thread 类 继承 Thread 类创建线程的步骤为: 1)创建一个类继承Thread类,重写run()方法,将所要完成的任务代码写进run(…

    Java 2023年6月15日
    084
  • python2的utf8编码问题

    Python中中文出现错误:SyntaxError: Non-ASCII character xxx in file x 在文件头部添加: #!/usr/bin/python -*…

    Java 2023年6月5日
    052
  • springBoot踩坑记录——持续更新ing

    以下都是springboot的默认配置,如果修改过springboot的配置文件则有可能不起作用。 springboot的resources下的目录作用 resources/tem…

    Java 2023年6月5日
    086
  • MySQL、Oracle元数据抽取分析

    最近接到个任务是抽取mysql和Oracle的元数据,大致就是在库里把库、schema、表、字段、分区、索引、主键等信息抽取出来,然后导成excel。 因为刚开始接触元数据,对这个…

    Java 2023年6月5日
    082
  • MySQL-InnoDB-MVCC多版本并发控制

    一、MySQL可重复读级别下,因为MVCC引起的BUG,下图1为相应的Java代码,其中事务1的生命周期最长,循环开启的事务2、3、4。。。与事务1并行 ,数据的读取只会成功一次,…

    Java 2023年6月16日
    045
  • 名字

    posted @2019-01-17 11:25 莫傷曉 阅读(93 ) 评论() 编辑 Original: https://www.cnblogs.com/mlxs/p/1028…

    Java 2023年6月15日
    071
  • 多线程

    Windows操作系统是多任务操作系统,它以进程为单位。每个独立执行的程序被称为一个进程,而每个进程又包含多个线程。系统可以分配给每个进程一段使用CPU的时间(CPU时间片),CP…

    Java 2023年6月5日
    068
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球