【Tomcat9源码分析】Container、Pipeline和Vavle设计

2023-11-21 16:40

本文主要是介绍【Tomcat9源码分析】Container、Pipeline和Vavle设计,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

转载请注明出处:http://blog.csdn.net/linxdcn/article/details/73800100


1 概述

如果你对Tomcat的整个框架、组件、请求流程不熟悉,建议你先阅读以下3篇Tomcat概述性的文章,再来看本篇文章:

【Tomcat9源码分析】组件与框架概述
【Tomcat9源码分析】生命周期、启动、停止概述
【Tomcat9源码分析】请求过程概述

Container是Tomcat中很重要的容器,主要包含Engine、Host、Context和Wrapper,其采用了责任链的设计模式,来处理一次请求。


2 Container分析

Container是一个接口,Tomcat提供了ContainerBase作为其实现的基类。

2.1 字段
public abstract class ContainerBase implements Container {// 子容器protected final HashMap<String, Container> children = new HashMap<>();// 监听事件protected final List<ContainerListener> listeners = new CopyOnWriteArrayList<>();// Container对应的Pipelineprotected final Pipeline pipeline = new StandardPipeline(this);// 领域对象private volatile Realm realm = null;
}
2.2 启动
public abstract class ContainerBase implements Container {@Overrideprotected synchronized void startInternal() throws LifecycleException {// 1 启动领域对象Realm realm = getRealmInternal();if (realm instanceof Lifecycle) {((Lifecycle) realm).start();}// 2 启动子容器Container children[] = findChildren();List<Future<Void>> results = new ArrayList<>();for (int i = 0; i < children.length; i++) {results.add(startStopExecutor.submit(new StartChild(children[i])));}// 3 启动Pipelineif (pipeline instanceof Lifecycle)((Lifecycle) pipeline).start();// 4 设置状态,启动本线程setState(LifecycleState.STARTING);threadStart();}
}
  1. 启动领域对象
  2. 启动子容器
  3. 启动Pipeline
  4. 设置状态,启动本线程

3 Pipeline分析

Pipeline是一个接口,其实现类是StandardPipeline

public class StandardPipeline extends LifecycleBase implements Pipeline {// 基础阀门protected Valve basic = null;// 关联的容器protected Container container = null;// 第一个阀门protected Valve first = null;@Overrideprotected synchronized void startInternal() throws LifecycleException {Valve current = first;if (current == null) {current = basic;}// 依次启动所有Value,Value是一个链表结构while (current != null) {if (current instanceof Lifecycle)((Lifecycle) current).start();current = current.getNext();}setState(LifecycleState.STARTING);}
}

4 Valve分析

Valve是一个接口,其基本实现的BaseValve类。

public abstract class ValveBase extends LifecycleMBeanBase implements Contained, Valve {// 关联的Containerprotected Container container = null;// 下一个Valveprotected Valve next = null;@Overridepublic Container getContainer() {return container;}// 初始化@Overrideprotected void initInternal() throws LifecycleException {super.initInternal();containerLog = getContainer().getLogger();}// 启动@Overrideprotected synchronized void startInternal() throws LifecycleException {setState(LifecycleState.STARTING);}
}

5 几个重要的Valve

5.1 StandardEngineValve
final class StandardEngineValve extends ValveBase {public final void invoke(Request request, Response response)throws IOException, ServletException {// 1 由request获取hostHost host = request.getHost();if (host == null) {// ...省略return;}// 2 调用host的pipeline的vavlehost.getPipeline().getFirst().invoke(request, response);}
}
  1. 根据request定位到可以处理的host对象
  2. 依次调用host里的pipeline上的valve
5.2 StandardEngineValve
final class StandardHostValve extends ValveBase {public final void invoke(Request request, Response response)throws IOException, ServletException {// 1 由request获取contextContext context = request.getContext();try {// 2 调用context里的pipeline上的valvecontext.getPipeline().getFirst().invoke(request, response);// response已经返回response.setSuspended(false);Throwable t = (Throwable) request.getAttribute(RequestDispatcher.ERROR_EXCEPTION);// 3 如果有错误,重定向到错误页if (response.isErrorReportRequired()) {if (t != null) {throwable(request, response, t);} else {status(request, response);}}} }
}
  1. 由request获取context
  2. 调用context里的pipeline上的valve
  3. 如果有错误,重定向到错误页
5.3 StandardContextValve
final class StandardContextValve extends ValveBase {@Overridepublic final void invoke(Request request, Response response)throws IOException, ServletException {// 由request获取wrapperWrapper wrapper = request.getWrapper();// ...省略// 调用wrapper里的pipeline上的valvewrapper.getPipeline().getFirst().invoke(request, response);}
}
  1. 由request获取wrapper
  2. 调用wrapper里的pipeline上的valve
5.4 StandardWrapperValve
final class StandardWrapperValve extends ValveBase {public final void invoke(Request request, Response response)throws IOException, ServletException {// 1 获取wrapper, contextStandardWrapper wrapper = (StandardWrapper) getContainer();Servlet servlet = null;Context context = (Context) wrapper.getParent();// 2 加载servlettry {if (!unavailable) {servlet = wrapper.allocate();}} // ...省略catch// 3 新建一个 filter 链表ApplicationFilterChain filterChain =ApplicationFilterFactory.createFilterChain(request, wrapper, servlet);// servlet会放在 filter 链表最后,并且最后会调用servlet的service方法try {if ((servlet != null) && (filterChain != null)) {// Swallow output if neededif (context.getSwallowOutput()) {// 4 调用 filter 链表上的 doFilterfilterChain.doFilter(request.getRequest(),response.getResponse());}} } // ...省略catch}
}
  1. 获取wrapper, context
  2. 加载servlet
  3. 新建一个 filter 链表,servlet会放在 filter 链表最后,并且最后会调用servlet的service方法
  4. 调用 filter 链表上的 doFilter

5 总结




转载请注明出处:http://blog.csdn.net/linxdcn/article/details/73800100

这篇关于【Tomcat9源码分析】Container、Pipeline和Vavle设计的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/403632

相关文章

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听

Java ArrayList扩容机制 (源码解读)

结论:初始长度为10,若所需长度小于1.5倍原长度,则按照1.5倍扩容。若不够用则按照所需长度扩容。 一. 明确类内部重要变量含义         1:数组默认长度         2:这是一个共享的空数组实例,用于明确创建长度为0时的ArrayList ,比如通过 new ArrayList<>(0),ArrayList 内部的数组 elementData 会指向这个 EMPTY_EL

如何在Visual Studio中调试.NET源码

今天偶然在看别人代码时,发现在他的代码里使用了Any判断List<T>是否为空。 我一般的做法是先判断是否为null,再判断Count。 看了一下Count的源码如下: 1 [__DynamicallyInvokable]2 public int Count3 {4 [__DynamicallyInvokable]5 get

怎么让1台电脑共享给7人同时流畅设计

在当今的创意设计与数字内容生产领域,图形工作站以其强大的计算能力、专业的图形处理能力和稳定的系统性能,成为了众多设计师、动画师、视频编辑师等创意工作者的必备工具。 设计团队面临资源有限,比如只有一台高性能电脑时,如何高效地让七人同时流畅地进行设计工作,便成为了一个亟待解决的问题。 一、硬件升级与配置 1.高性能处理器(CPU):选择多核、高线程的处理器,例如Intel的至强系列或AMD的Ry

SWAP作物生长模型安装教程、数据制备、敏感性分析、气候变化影响、R模型敏感性分析与贝叶斯优化、Fortran源代码分析、气候数据降尺度与变化影响分析

查看原文>>>全流程SWAP农业模型数据制备、敏感性分析及气候变化影响实践技术应用 SWAP模型是由荷兰瓦赫宁根大学开发的先进农作物模型,它综合考虑了土壤-水分-大气以及植被间的相互作用;是一种描述作物生长过程的一种机理性作物生长模型。它不但运用Richard方程,使其能够精确的模拟土壤中水分的运动,而且耦合了WOFOST作物模型使作物的生长描述更为科学。 本文让更多的科研人员和农业工作者

MOLE 2.5 分析分子通道和孔隙

软件介绍 生物大分子通道和孔隙在生物学中发挥着重要作用,例如在分子识别和酶底物特异性方面。 我们介绍了一种名为 MOLE 2.5 的高级软件工具,该工具旨在分析分子通道和孔隙。 与其他可用软件工具的基准测试表明,MOLE 2.5 相比更快、更强大、功能更丰富。作为一项新功能,MOLE 2.5 可以估算已识别通道的物理化学性质。 软件下载 https://pan.quark.cn/s/57

工厂ERP管理系统实现源码(JAVA)

工厂进销存管理系统是一个集采购管理、仓库管理、生产管理和销售管理于一体的综合解决方案。该系统旨在帮助企业优化流程、提高效率、降低成本,并实时掌握各环节的运营状况。 在采购管理方面,系统能够处理采购订单、供应商管理和采购入库等流程,确保采购过程的透明和高效。仓库管理方面,实现库存的精准管理,包括入库、出库、盘点等操作,确保库存数据的准确性和实时性。 生产管理模块则涵盖了生产计划制定、物料需求计划、

基于51单片机的自动转向修复系统的设计与实现

文章目录 前言资料获取设计介绍功能介绍设计清单具体实现截图参考文献设计获取 前言 💗博主介绍:✌全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师,一名热衷于单片机技术探索与分享的博主、专注于 精通51/STM32/MSP430/AVR等单片机设计 主要对象是咱们电子相关专业的大学生,希望您们都共创辉煌!✌💗 👇🏻 精彩专栏 推荐订阅👇🏻 单片机