深入剖析Tomcat(十二) 详解StandardContext

StandardContext是Context容器的一个标准实现,一般情况下,Tomcat都是使用StandardContext类来创建Context容器。前面讲过,Context容器代表了一个Web应用,Tomcat本身支持部署多个应用,相应的每个应用都会有一个StandardContext实例来对应。在使用SpringBoot的前提下,一个Tomcat也就仅创建一个StandardContext实例,来服务这个SpringBoot框架对应的应用。

StandardContext既然针对的是一整个Web应用,那这个Web应用的功能就需要靠它来支撑起来,StandardContext通过一系列组件来实现它的功能。

载入器

Tomcat规定了每个Context容器都只加载自己应用下的类,不能加载该Tomcat下其他应用的类,所以,StandardContext持有一个“载入器(Loader)”对象,用来加载该应用程序下的所有类(servlet及相关类)。Loader的标准实现为WebappLoader。

重载

StandardContext中有一个reloadable属性,通过 setReloadable 方法可以设置它的值,如果设为true的话,证明该Context容器支持重载,Tomcat会安排一个后台线程不断地检查该Context关联的class及jar包的最后修改日期,如果发现有变化,就会重新加载该Context容器下的所有类。如果reloadable设为false,那么该Context容器不支持重载。

会话(session)

会话也是维护在Context这一层的,所以StandardContext中持有“会话管理器(Manager)”对象,来管理针对该Web应用的会话。Manager的标准实现为StandardManager,单个session的标准实现为StandardSession(实现了HttpSession接口)。session只在需要时才会创建,Tomcat会安排一个后台线程不断检查session对象有没有过期,如果过期了就将其失效。

子容器与映射器

一个Web应用程序一般来说会有多个servlet实例,一个servlet就对应一个Wrapper容器实例,所以一个Context实例下就会管理多个Wrapper实例,这些Wrapper实例称为Context的“子容器”。当Context接收到一个servlet请求后,需要知道该把这个请求具体交给哪个Wrapper来处理,这其间就需要有个映射关系了,将servlet的请求uri映射到具体的Wrapper上,StandardContext就持有一个“映射器(Mapper)”对象来实现这个映射逻辑。

StandardContext中维护了 servletMappings 与 children 两个map集合,通过这两个map,很容易就可以根据请求uri找到对应的Wrapper实例。

来看一下“映射器”是如何实现此映射逻辑的,StandardContextMapper是映射器的标准实现,其中的map方法就是通过request找Wrapper的方法,下面是缩减版的代码

public Container map(Request request, boolean update) {// 获取相对路径uri  (假设请求的资源路径为 /myapp/animal/tom, /myapp 代表部署在Tomcat中的应用名为myapp)String contextPath = ((HttpServletRequest) request.getRequest()).getContextPath();   //结果示例: “/myapp”String requestURI = ((HttpRequest) request).getDecodedRequestURI();                  //结果示例: “/myapp/animal/tom”String relativeURI = requestURI.substring(contextPath.length());                     //结果示例: “/animal/tom”Wrapper wrapper = null;if (!(relativeURI.equals("/")))name = context.findServletMapping(relativeURI);if (name != null)wrapper = (Wrapper) context.findChild(name);return wrapper;
}

上面映射器的逻辑是Tomcat4的逻辑,自Tomcat5之后,获取Wrapper的代码被放到了Request对象中,StandardContextMapper这个类也没有了,但是整体逻辑大致想通,明白思想即可。

start() 与 invoke()

上面列举了StandardContext中持有的比较重要的几个组件,各个组件也为StandardContext提供了相应的功能实现。而StandardContext具体应用这些组件的逻辑则主要集中在两个方法中:start()与invoke()。

start()方法是一个生命周期方法,Tomcat启动时会调用所有组件的start()方法,在StandardContext中,start()方法主要完成的功能是

  • 配置资源,识别到该Context容器对应的应用目录,将class及jar纳入自己的资源库中。
  • 创建各个组件实例,并调用各组件的start()方法完成组件的初始化。
  • 创建各个子容器(Wrapper)实例,并调用子容器的start()方法完成子容器的初始化。

start()方法主要是完成Context的一系列初始化操作,start()方法执行成功后,该StandardContext就可以对外工作了。

invoke()方法是StandardContext处理具体请求的方法,当一个servlet请求打进来后,就会进入到invoke()方法中,StandardContext#invoke()方法逻辑很简单,就是调用了一下它的Pipeline组件的invoke方法,其实真正对请求进行处理的对象是该Pipeline的基础阀:StandardContextValve。StandardContextValve#invoke() 方法会调用到映射器的map方法,根据请求uri找到指定Wrapper对象,然后调用Wrapper对象的invoke()方法,等Wrapper#invoke()方法执行结束后,StandardContext对本次servlet请求的处理也就基本完成了。(Wrapper#invoke()方法的逻辑请参考上一篇文章)。

在servlet的service方法中,如果有获取session的逻辑,那么StandardContext就会为其去寻找session,如果没有找到就会创建一个session给servlet用。具体逻辑可以参考第九篇文章。

StandardContext的基本逻辑就讲到这里,这篇文章串联了前些篇文章的知识,将StandardContext的完整脉络呈现了一下。下篇文章来研究下Host与Engine两种容器。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/860460.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

实用软件下载:ABBYY Finereader 15最新安装包及详细安装教程

数据表明FineReader PDF提供实用、简易的工具,将纸质文档和PDF结合起来,提高了数字工作场所的效率。我们都知道 即时背景识别:使不可搜索的PDF能够在工作中立即使用。值得一提的是文档转换更精准:OCR技术,它提高了PDF转换、布局保…

基于STM32的简易计算器proteus仿真设计(仿真+程序+设计报告+讲解视频)

基于STM32的简易计算器proteus仿真设计 讲解视频1.主要功能2. 仿真3. 程序4. 设计报告5. 资料清单&下载链接 基于STM32的简易计算器proteus仿真设计(仿真程序设计报告讲解视频) 仿真图proteus 8.9 程序编译器:keil 5 编程语言:C语言 …

深入JVM:详解JIT即时编译器

文章目录 深入JVM:详解JIT即时编译器一、序言二、基础概念1、何为JIT即时编译2、热点代码 三、HotSpot内置的即时编译器1、C1编译器2、C2编译器3、分层编译3.1 协作流程 四、常见JIT优化技术1、方法内联2、逃逸分析(1)同步锁消除(…

数据结构:栈和队列详解

栈 栈的概念 栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守先进后出LIFO(Last In First Out)的原则。大家可以理解为…

Day60 代码随想录打卡|回溯算法篇---组合

题目(leecode T77): 给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 方法:本题最直观的解法是使用暴力for循环遍历法,根据k的大小定for循环的嵌套次数&…

Posix消息队列使用总结

Posix在线文档: The Single UNIX Specification, Version 2 (opengroup.org) Linux系统中提供了两种不同接口的消息队列: POSIX消息队列。POSIX为可移植的操作系统接口。System V消息队列。System V 是 AT&T 的第一个商业UNIX版本(UNIX System III)的…

[Python人工智能] 四十六.PyTorch入门 (1)环境搭建、神经网络普及和Torch基础知识

从本专栏开始,作者正式研究Python深度学习、神经网络及人工智能相关知识。前文讲解合如何利用keras和tensorflow构建基于注意力机制的CNN-BiLSTM-ATT-CRF模型,并实现中文实体识别研究。这篇文章将介绍PyTorch入门知识。前面我们的Python人工智能主要以TensorFlow和Keras为主,…

【Linux】进程间通信_4

文章目录 七、进程间通信1. 进程间通信分类systeam V共享内存消息队列信号量 未完待续 七、进程间通信 1. 进程间通信分类 systeam V共享内存 进程间通信的本质就是让不同进程看到同一份资源。而systeam V是通过让不同的进程经过页表映射到同一块内存空间(操作系…

LED显示屏中什么是静态驱动?什么是扫描驱动?两者的区别是什么?

随着科技的飞速发展,LED显示屏作为现代信息显示技术的重要组成部分,正以其独特的优势引领着显示行业的革新。近日,LED显示屏市场呈现出蓬勃的发展态势,技术创新不断推动行业向前发展,让LED显示屏无论是在商场的广告牌、…

苏东坡传-读书笔记一

太守的官衙位于杭州中心,但是苏东坡却喜欢在较为富有诗意的地方办公。他往往在葛岭下面有十三间房子的寿星院办公,因为那里风光如画。看公文不在寒碧轩,就在雨奇堂。我们记得雨奇堂是从苏东坡西湖诗“山色空濛雨亦奇”而得名的。在这里&#…

04-Shell编程之正则表达式与文本处理器

4.1 正则表达式 4.1.1正则表达式概述 1.正则表达式的定义 正则表达式又称正规表达式,常规表达式。在代码中常简写为regex,regexp,或RE。正则表达式是使用一个字符来描述,匹配一系列符合某个句法规则的字符串,简单的…

【现代操作系统】什么是操作系统

1.前言 现代计算机系统由一个或多个处理器、主存、磁盘、打印机、键盘、鼠标、显示器、网络接口以及各种其他输入/输出设备组成。一般而言,现代计算机系统是一个复杂的系统。如果每位应用程序员都不得不掌握系统的所有细节,那就不可能再编写代码了。而且…

音视频入门基础:H.264专题(5)——FFmpeg源码中 解析NALU Header的函数分析

音视频入门基础:H.264专题系列文章: 音视频入门基础:H.264专题(1)——H.264官方文档下载 音视频入门基础:H.264专题(2)——使用FFmpeg命令生成H.264裸流文件 音视频入门基础&…

SpringBoot-在配置文件中使用Profile

Profile,译为“配置文件” 在这里的Spring Boot也是一样,我们可以配置很多个Profile,每个Profile都对应一整个完整的全局配置,激活哪个,那个对应的全局配置就生效,具体的配置: 1、properties格…

漏洞挖掘 | 记一次edusrc--轻松拿下中危信息泄露

1.前言 也是一次漏洞挖掘的思路分享 上次我们讲过了关于小程序方面的一些小思路,即关于抓包更改id号造成的一个信息泄露,但是在小程序上的信息泄露很难涉及到公民三要素这是一个痛点,今天就来分享一下一次edu挖掘时挖到的一个涉及公民三要素…

【讲师招募】PowerData 2024数字经济开源行

【讲师招募】PowerData 2024数字经济开源行 活动信息讲师招募往期活动回顾 活动信息 2023,社区经过一年的发展,凝聚起了一批热爱数据、热爱开源的伙伴。 2024,社区计划在全国十个城市举办"数字经济-城市开源行"活动,连…

2024年最新中级会计职称考试题库。

46.甲将一汇票背书转让给乙,但该汇票上未记载乙的名称。其后,乙在该汇票被背书人栏内记载了自己的名称。根据《票据法》的规定,下列有关该汇票背书与记载效力的表述中,正确的是()。 A.甲的背书无效&#x…

Qt案例-ApplicationExamples-Calqlatr

项目 一个Qt Quick应用程序设计的横向和纵向设备,使用自定义组件,响应式布局和JavaScript的应用程序逻辑。 项目路径: Qt\Examples\Qt-6.7.1\demos 环境:Qt6.7.1 MSVC 2019 64位 项目目录: calqlatr--CMakeList.txt…

三、用户中心项目笔记----后端多环境实战+原始部署

后端多环境主要是修改: 依赖的环境地址 数据库地址 缓存地址 消息队列地址 项目端口号 服务器配置 后端怎么去区分不同的环境? 我们后端的SpringBoot项目,通过application.yml添加不同后缀来区分配置文件 application.yml就是公共的配置&a…

Sam Altman:从少儿奇才到OpenAI掌舵人

自2022年底发布了ChatGPT以来,OpenAI及其首席执行官Sam Altman迅速成为科技界的焦点人物。Altman的崛起并非偶然,而是长期以来不断追求权力和创新的结果。本文将回顾Altman的成长历程,探索他如何一步步走向OpenAI的顶峰。 童年与教育背景 S…