Tomcat源码分析(三)-Container和Lifecycle

TongWeb7应用开发手册.pdf TongWeb7应用开发手册.pdf TongWeb7应用开发手册.pdf TongWeb7应用开发手册.pdf 立即下载

一、Tomcat生命周期的管理

 Tomcat通过package org.apache.catalina.Lifecycle;接口管理Tomcat的生命周期。


package org.apache.catalina;

public interface Lifecycle {
//定义的String常量,用于LifecycleEvent事件的type属性中,作用是区分组件发出的LifecycleEvent事件时的状态(如初始化前,启动前,启动中等)

    public static final String BEFORE_INIT_EVENT = "before_init";

    public static final String AFTER_INIT_EVENT = "after_init";

    public static final String START_EVENT = "start";

    public static final String BEFORE_START_EVENT = "before_start";

    public static final String AFTER_START_EVENT = "after_start";

    public static final String STOP_EVENT = "stop";

    public static final String BEFORE_STOP_EVENT = "before_stop";

    public static final String AFTER_STOP_EVENT = "after_stop";

    public static final String AFTER_DESTROY_EVENT = "after_destroy";

    public static final String BEFORE_DESTROY_EVENT = "before_destroy";

    public static final String PERIODIC_EVENT = "periodic";

    public static final String CONFIGURE_START_EVENT = "configure_start";

    public static final String CONFIGURE_STOP_EVENT = "configure_stop";

    public void addLifecycleListener(LifecycleListener listener); //添加LifecycleListener
                                                                  //监听器

    public LifecycleListener[] findLifecycleListeners(); 

    public void init() throws LifecycleException;

  
    public void start() throws LifecycleException;

    public void stop() throws LifecycleException;

    public void destroy() throws LifecycleException;

    public LifecycleState getState();

    public String getStateName();

    public interface SingleUse {
    }
}

 

所有生命周期的组件都要实现Lifecycle接口。

LifecycleBase是Lifecycle的默认实现。Server,Service等生命周期组件直接或间接继承了LifecycleBase;

LifecycleBase里面定义了一个 LifecycleSupport类来管理监听器。

 /**
     * Used to handle firing lifecycle events.
     * TODO: Consider merging LifecycleSupport into this class.
     */
    private final LifecycleSupport lifecycle = new LifecycleSupport(this);

LifecycleSupport代码如下:

 

/**
 * Support class to assist in firing LifecycleEvent notifications to
 * registered LifecycleListeners.
 *
 * @author Craig R. McClanahan
 */
public final class LifecycleSupport {

    // ----------------------------------------------------------- Constructors

    /**
     * Construct a new LifecycleSupport object associated with the specified
     * Lifecycle component.
     *
     * @param lifecycle The Lifecycle component that will be the source
     *  of events that we fire
     */
    public LifecycleSupport(Lifecycle lifecycle) {
        super();
        this.lifecycle = lifecycle;
    }


    // ----------------------------------------------------- Instance Variables

    /**
     * The source component for lifecycle events that we will fire.
     */
    private final Lifecycle lifecycle;


    /**
     * The list of registered LifecycleListeners for event notifications.
     */
    private final List<LifecycleListener> listeners = new CopyOnWriteArrayList<>();


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

    /**
     * Add a lifecycle event listener to this component.
     *
     * @param listener The listener to add
     */
    public void addLifecycleListener(LifecycleListener listener) {
        listeners.add(listener);
    }


    /**
     * Get the lifecycle listeners associated with this lifecycle. If this
     * Lifecycle has no listeners registered, a zero-length array is returned.
     */
    public LifecycleListener[] findLifecycleListeners() {
        return listeners.toArray(new LifecycleListener[0]);
    }


    /**
     * Notify all lifecycle event listeners that a particular event has
     * occurred for this Container.  The default implementation performs
     * this notification synchronously using the calling thread.
     *
     * @param type Event type
     * @param data Event data
     */
    public void fireLifecycleEvent(String type, Object data) {
        LifecycleEvent event = new LifecycleEvent(lifecycle, type, data);
        for (LifecycleListener listener : listeners) {
            listener.lifecycleEvent(event);
        }
    }


    /**
     * Remove a lifecycle event listener from this component.
     *
     * @param listener The listener to remove
     */
    public void removeLifecycleListener(LifecycleListener listener) {
        listeners.remove(listener);
    }
}

而在LifecycleSupport类里面定义了一个LifecycleListener集合类型来保存LifecycleListener监听器。

代码如下:

/**
 * Support class to assist in firing LifecycleEvent notifications to
 * registered LifecycleListeners.
 *
 * @author Craig R. McClanahan
 */
public final class LifecycleSupport {

    // ----------------------------------------------------------- Constructors

    /**
     * Construct a new LifecycleSupport object associated with the specified
     * Lifecycle component.
     *
     * @param lifecycle The Lifecycle component that will be the source
     *  of events that we fire
     */
    public LifecycleSupport(Lifecycle lifecycle) {
        super();
        this.lifecycle = lifecycle;
    }


    // ----------------------------------------------------- Instance Variables

    /**
     * The source component for lifecycle events that we will fire.
     */
    private final Lifecycle lifecycle;


    /**
     * The list of registered LifecycleListeners for event notifications.
     */
    private final List<LifecycleListener> listeners = new CopyOnWriteArrayList<>();


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

    /**
     * Add a lifecycle event listener to this component.
     *
     * @param listener The listener to add
     */
    public void addLifecycleListener(LifecycleListener listener) {
        listeners.add(listener);
    }


    /**
     * Get the lifecycle listeners associated with this lifecycle. If this
     * Lifecycle has no listeners registered, a zero-length array is returned.
     */
    public LifecycleListener[] findLifecycleListeners() {
        return listeners.toArray(new LifecycleListener[0]);
    }


    /**
     * Notify all lifecycle event listeners that a particular event has
     * occurred for this Container.  The default implementation performs
     * this notification synchronously using the calling thread.
     *
     * @param type Event type
     * @param data Event data
     */
    public void fireLifecycleEvent(String type, Object data) {
        LifecycleEvent event = new LifecycleEvent(lifecycle, type, data);
        for (LifecycleListener listener : listeners) {
            listener.lifecycleEvent(event);
        }
    }


    /**
     * Remove a lifecycle event listener from this component.
     *
     * @param listener The listener to remove
     */
    public void removeLifecycleListener(LifecycleListener listener) {
        listeners.remove(listener);
    }
}

LifecycleListener类代码如下:

/**
 * Interface defining a listener for significant events (including "component
 * start" and "component stop" generated by a component that implements the
 * Lifecycle interface. The listener will be fired after the associated state
 * change has taken place.
 *
 * @author Craig R. McClanahan
 */
public interface LifecycleListener {


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


}

 

   二、 LifecycleBase类的生命周期方法分析:

           四个生命周期方法分别是 init(),start(),stop(),destroy()方法。都会线判断状态和当前方法是否匹配。

            如在init方法之前调用了start方法。这时会先执行init方法。

             LifecycleBase的状态是通过LifecycleBase类型的state属性来保存的,最开始初始化值为LifecycleState.NEW.
           initInternal()和startInternal()模板方法会调用具体的子类具体来启动。

 LifecycleBase类的init方法代码如下:

 

  @Override
    public final synchronized void init() throws LifecycleException {
        if (!state.equals(LifecycleState.NEW)) {//如果状态不是NEW,就
            invalidTransition(Lifecycle.BEFORE_INIT_EVENT);
        }

        try { //初始化前将状态设置为LifecycleState.INITIALIZING
            setStateInternal(LifecycleState.INITIALIZING, null, false);
            initInternal(); //具体执行初始化
            setStateInternal(LifecycleState.INITIALIZED, null, false);
        } catch (Throwable t) {
            ExceptionUtils.handleThrowable(t);
            setStateInternal(LifecycleState.FAILED, null, false);
            throw new LifecycleException(
                    sm.getString("lifecycleBase.initFail",toString()), t);
        }
    }


    protected abstract void initInternal() throws LifecycleException;
   //invalidTransition 抛出LifecycleException异常  
   //处理不符合要求的状态
   private void invalidTransition(String type) throws LifecycleException {
        String msg = sm.getString("lifecycleBase.invalidTransition", type,
                toString(), state);
        throw new LifecycleException(msg);
    }
   private synchronized void setStateInternal(LifecycleState state,
            Object data, boolean check) throws LifecycleException {

        if (log.isDebugEnabled()) {
            log.debug(sm.getString("lifecycleBase.setState", this, state));
        }

        if (check) {  //check 该段主要是校验state状态,state为null抛出异常,
                      //state不是FAILED 并且state不是STARTING或者this.state不是STARTING_PREP 或state不是STARTING,this.state也不是STARTING_PREP (省略。。)才会抛出异常,无法识别得到state.
                      //state可以是FAILED 
                      //state可以是STARTING,this.state可以是STARTING_PREP 
                      //state可以是STOPPING,this.state可以是STOPPING_PREP 
                      //state可以是STOPPING,this.state可以是FAILED 都不会进入异常
            // Must have been triggered by one of the abstract methods (assume
            // code in this class is correct)
            // null is never a valid state
            if (state == null) {
                invalidTransition("null");
                // Unreachable code - here to stop eclipse complaining about
                // a possible NPE further down the method
                return;
            }

            // Any method can transition to failed
            // startInternal() permits STARTING_PREP to STARTING
            // stopInternal() permits STOPPING_PREP to STOPPING and FAILED to
            // STOPPING
            if (!(
                    state == LifecycleState.FAILED ||
                    (this.state == LifecycleState.STARTING_PREP &&
                            state == LifecycleState.STARTING) ||
                    (this.state == LifecycleState.STOPPING_PREP &&
                            state == LifecycleState.STOPPING) ||
                    (this.state == LifecycleState.FAILED &&
                            state == LifecycleState.STOPPING)
                    )) {
                // No other transition permitted
                invalidTransition(state.name());
            }
        }

        this.state = state;
        String lifecycleEvent = state.getLifecycleEvent();
        if (lifecycleEvent != null) {  
            fireLifecycleEvent(lifecycleEvent, data); //处理事件
        }
    }

setStateInternal()方法中通过check参数来判断是否需要检查传入的状态state.如果需要检查则会检查传入的状态是否为空和是否符合正确的状态,最后设置state.

 LifecycleBase类的start方法代码如下:

/**
     * {@inheritDoc}
     */
    @Override
    public final synchronized void start() throws LifecycleException {
        //检查状态是否已经启动,如果已经启动打印log
        if (LifecycleState.STARTING_PREP.equals(state) || LifecycleState.STARTING.equals(state) ||
                LifecycleState.STARTED.equals(state)) {

            if (log.isDebugEnabled()) {
                Exception e = new LifecycleException();
                log.debug(sm.getString("lifecycleBase.alreadyStarted", toString()), e);
            } else if (log.isInfoEnabled()) {
                log.info(sm.getString("lifecycleBase.alreadyStarted", toString()));
            }

            return;
        }

        if (state.equals(LifecycleState.NEW)) {
            init();
        } else if (state.equals(LifecycleState.FAILED)) { //状态失败停止
            stop();
        } else if (!state.equals(LifecycleState.INITIALIZED) &&
                !state.equals(LifecycleState.STOPPED)) {  //如果状态无法识别,抛出异常
            invalidTransition(Lifecycle.BEFORE_START_EVENT);
        }

        try {
            setStateInternal(LifecycleState.STARTING_PREP, null, false);
            startInternal();
            if (state.equals(LifecycleState.FAILED)) {
                // This is a 'controlled' failure. The component put itself into the
                // FAILED state so call stop() to complete the clean-up.
                stop();
            } else if (!state.equals(LifecycleState.STARTING)) {//如果启动后状态不是
                                                               //STARTING则抛出异常
                // Shouldn't be necessary but acts as a check that sub-classes are
                // doing what they are supposed to.
                invalidTransition(Lifecycle.AFTER_START_EVENT);
            } else {                                          
                                                          //启动成功后将状态设为STARTED
                setStateInternal(LifecycleState.STARTED, null, false);
            }
        } catch (Throwable t) {
            // This is an 'uncontrolled' failure so put the component into the
            // FAILED state and throw an exception.
            ExceptionUtils.handleThrowable(t);
            setStateInternal(LifecycleState.FAILED, null, false);
            throw new LifecycleException(sm.getString("lifecycleBase.startFail", toString()), t);
        }
    }

 

三、Container源码分析

    Container的作用是具体负责处理Servlet,处理Http请求。

 

public interface Container extends Lifecycle {

Container 四个子容器 Engine,Host,Context,Wrapper逐层包含的关系。

Engine 引擎,用来管理多个站点。

Host 站点(虚拟主机),整个webapps是一个站点,如:www.test.com域名对应webapps目录所代表的站点,其中ROOT目录 是主应用,直接使用域名就可以访问主应用。而webapps/test是test子应用,访问www.test.com/test

Context 应用程序,默认配置下webapps下的每个目录都市一个应用。其中ROOT目录存放着主应用,其他目录是子应用。

Wrapper 每个Wrapper封装一个Servlet.

 

 

配置:

Server.xml文件里面放了Tomcat大部分功能的配置。

Server.xml文件默认配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<Server port="8005" shutdown="SHUTDOWN">
  <Listener className="org.apache.catalina.startup.VersionLoggerListener"/>
  <Listener SSLEngine="on" className="org.apache.catalina.core.AprLifecycleListener"/>
  <Listener className="org.apache.catalina.core.JasperListener"/>
  <!-- Prevent memory leaks due to use of particular java/javax APIs-->
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener"/>
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/>
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener"/>
  <GlobalNamingResources>
    <Resource auth="Container" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" name="UserDatabase" pathname="conf/tomcat-users.xml" type="org.apache.catalina.UserDatabase"/>
  </GlobalNamingResources>

  <Service name="Catalina">
    <Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443"/>
    <Engine defaultHost="localhost" name="Catalina">
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>
      </Realm>

      <Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true">
        <Valve className="org.apache.catalina.valv
ADS入门学习笔记——射频振荡器的设计 振荡器是射频系统中的基本部件之一,可以将直流功率转换为射频功率,在特定的频率点建立起稳定的正弦振荡,成为所需的射频信号源。 阅读详情

相关推荐

logisim计组实验八 乘法器

原理:点这里 有问题欢迎留言哦~ 文章目录五位阵列乘法器电路图时间延迟分析六位补码阵列乘法器五位无符号乘法流水线原理图电路图原码一位乘法器原理图电路图补码一位乘法器 五位阵列乘法器 电路图 此处注意:全加器FA的cout端是进位端而非输出端 使用硬件控制比循环累加的速度快得多。 但是存在串行进位链 改进版: 时间延迟分析 T是计算相加数的一级门延迟 3n–>2n 性能差别在1.5倍 ...

treblez's blog 2万+

人工智能情感分析实战:文本情绪识别

人工智能情感分析,特别是文本情绪识别,已成为理解和处理人类情感信息的重要工具。通过数据预处理、特征提取、模型训练与评估等步骤,我们可以有效地从文本数据中提取情感信息,为各种应用场景提供有价值的洞察。随着技术的不断进步和创新,情感分析的应用前景将更加广阔,为我们的生活和工作带来更多便利和机遇。

shejizuopin的博客 1097

字节跳动高频111道核心前端面试题解析,web开发增强

但是本人觉得看书也很必要,可以节省很多时间,常见的javascript的书,例如:javascript的高级程序设计,是每位前端工程师必不可少的一本书,边看边用,了解js的一些基本知识,基本上很全面了,如果有时间可以读一些,js性能相关的书籍,以及设计者模式,在实践中都会用的到。内容包括html,css,JavaScript,ES6,计算机网络,浏览器,工程化,模块化,Node.js,框架,数据结构,性能优化,项目等等。自定义指令(v-check、v-focus)的方法有哪些?v-model是什么?

2401_84094620的博客 1200

深度解析大语言模型中的词向量

​ 在学习完语言模型中的编码器与解码器知识后,让我们继续深入学习大语言模型中一个非常关键的技术:词向量表示,以及如何通过Transformer模型实现对next token的预测。 ​

产品老A,8年互联网大厂AIPM,专注探索新型人机交互 3284

Oracle EBS(R12+)通过Multi-Org 多组织架构、Multi-Ledger 多账簿、SLA 子分类账会计、多币种引擎、多会计政策并行五大核心能力,为跨国企业提供一体化、自动化、合规的

Oracle EBS(R12+)提供全球会计核算解决方案,通过Multi-Org多组织架构实现跨国集团数据隔离与共享,支持四层组织结构(业务组→法律实体→经营单位→库存组织)。Multi-Ledger多账簿功能允许一笔业务多准则自动核算,包含主账簿、辅助账簿和报告币种。系统内置多币种处理引擎,覆盖全流程货币业务,支持自动重估、再计量和折算。通过SLA子分类账会计实现多会计政策并行处理,满足不同国家会计准则和税制要求。该方案可同时支持本地法定、集团合并及管理分析需求,实现全球财务数据集中管理,提升合规性和运营

金牌架构师 553

【技术科普】破解政务跨系统数据壁垒!亘川一网统管平台多源数据同步技术解析

本文解析亘川一网统管平台多源数据同步技术,针对政务跨系统数据壁垒难题,介绍组件的数据采集、校验、审计留痕等核心能力,结合营商环境项目落地案例,对比传统开发模式差异,讲解开源组件的实践价值,为政务项目开发者提供落地参考。

weixin_67440240的博客 635

UE5实现建筑剖切效果

UE5实现建筑剖切效果

专注GIS开发 8464

【Java基础知识 19】Java接口的作用和意义

Java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。

学Java,找哪吒 2万+

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

上一篇: Tomcat源码分析(二)-Tomcat的启动流程以及分析
下一篇: Tomcat源码分析(四)-Connector
Jacabe博客-编程
博客等级 码龄12年 320粉丝 57原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值