Tomcat组件化设计

1 组件化及可配置

Tomcat整体架构基于组件,可通过XML或代码配置组件。如server.xml配置Tomcat的连接器及容器组件。

Tomcat提供一堆积木,怎么搭建这些积木你决定,你可根据需要灵活选择组件搭建你的Web容器,并且可自定义组件。

2 Web容器如何实现这种组件化设计?

2.1 面向接口编程

要对系统功能按“高内聚、低耦合”原则拆分,每个组件都有相应接口,组件间通过接口通信,就可方便替换组件。如选择不同连接器类型,只要这些连接器组件实现同一接口即可。

2.2 组装

Web容器提供一个载体把组件组装在一起工作。组件的工作无非就是处理请求,因此容器通过责任链模式把请求依次交给组件去处理。

对用户,只需告诉Web容器由哪些组件处理请求。把组件组织起来需要一个“管理者”,所以Tomcat有Server,即组件的载体,Server包含连接器组件、容器组件。容器还要把请求交给各子容器组件处理,Tomcat和Jetty都是责任链模式。

用户通过配置组装组件,类似Spring中Bean的DI。Spring的用户可通过配置文件或注解方式组装Bean,Bean与Bean的依赖关系完全由用户自定义。这和Web容器不同,Web容器中组件与组件之间的关系是固定的,比如Tomcat中Engine组件下有Host组件、Host组件下有Context组件等,但你不能在Host组件里“注入”一个Wrapper组件,这是由于Web容器本身的功能来决定的。

3 创建组件

由于组件可配置,Web容器在启动前并不知道要创建哪些组件,即不能通过硬编码实例化这些组件,而要通过反射。即Web容器通过Class.forName创建组件。 无论哪种方式,在实例化类前,Web容器需把组件类加载到JVM,这涉及类加载,Web容器设计自己的类加载器。

Spring也是通过反射机制来动态地实例化Bean,那么它用到的类加载器哪来的? Web容器给每个Web应用创建了一个类加载器,Spring用到的类加载器是Web容器传给它!

4 组件的生命周期管理

不同类型的组件具有父子层次关系,父组件处理请求后再把请求传递给某个子组件。 Tomcat通过容器,把小容器放到大容器以实现父子关系。

Tomcat采用类似办法管理组件的生命周期:

  • 父组件负责子组件的创建、启停和销毁 只要启动最上层组件,整个Web容器就被启动,即一键启停
  • Tomcat定义了组件的生命周期状态,并把组件状态的转变定义成事件 一个组件的状态变化会触发子组件变化,比如Host容器的启动事件里会触发Web应用的扫描和加载,最终会在Host容器下创建相应的Context容器,而Context组件的启动事件又会触发Servlet的扫描,进而创建Wrapper组件。 如何实现这种联动? 观察者模式,创建监听器去监听容器的状态变化,在监听器的方法里去实现相应的动作,这些监听器其实是组件生命周期过程中的“扩展点”。

Spring也采用类似设计,Spring给Bean生命周期状态提供“扩展点”。这些扩展点定义成一个个接口,只要Bean实现这些接口,Spring就会负责调用这些接口,这样当Bean的创建、初始化和销毁这些控制权交给Spring后,Spring让你有机会在Bean的整个生命周期中执行你的逻辑。

5 模板模式

Tomcat大量采用骨架抽象类和模板模式。如Tomcat#ProtocolHandler接口,ProtocolHandler的抽象基类AbstractProtocol实现协议处理层的骨架和通用逻辑。

具体协议也有抽象基类,如HttpProtocol和AjpProtocol。这些抽象骨架类实现通用逻辑,并定义一些抽象方法,这些抽象方法由子类实现,抽象骨架类调用抽象方法实现骨架逻辑。

JDK也有这种设计,如Java集合的AbstractSet、AbstractMap。 Java 8开始允许接口有default方法,开始可以把抽象骨架类的通用逻辑放到接口。

6 总结

Web容器为了支持这种组件化设计,遵循了一些规范,比如面向接口编程,用“管理者”去组装这些组件,用反射的方式动态的创建组件、统一管理组件的生命周期,并且给组件生命状态的变化提供了扩展点,组件的具体实现一般遵循骨架抽象类和模板模式。

原文地址:https://cloud.tencent.com/developer/article/2192097

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


学习编程是顺着互联网的发展潮流,是一件好事。新手如何学习编程?其实不难,不过在学习编程之前你得先了解你的目的是什么?这个很重要,因为目的决定你的发展方向、决定你的发展速度。
IT行业是什么工作做什么?IT行业的工作有:产品策划类、页面设计类、前端与移动、开发与测试、营销推广类、数据运营类、运营维护类、游戏相关类等,根据不同的分类下面有细分了不同的岗位。
女生学Java好就业吗?女生适合学Java编程吗?目前有不少女生学习Java开发,但要结合自身的情况,先了解自己适不适合去学习Java,不要盲目的选择不适合自己的Java培训班进行学习。只要肯下功夫钻研,多看、多想、多练
Can’t connect to local MySQL server through socket \'/var/lib/mysql/mysql.sock问题 1.进入mysql路径
oracle基本命令 一、登录操作 1.管理员登录 # 管理员登录 sqlplus / as sysdba 2.普通用户登录
一、背景 因为项目中需要通北京网络,所以需要连vpn,但是服务器有时候会断掉,所以写个shell脚本每五分钟去判断是否连接,于是就有下面的shell脚本。
BETWEEN 操作符选取介于两个值之间的数据范围内的值。这些值可以是数值、文本或者日期。
假如你已经使用过苹果开发者中心上架app,你肯定知道在苹果开发者中心的web界面,无法直接提交ipa文件,而是需要使用第三方工具,将ipa文件上传到构建版本,开...
下面的 SQL 语句指定了两个别名,一个是 name 列的别名,一个是 country 列的别名。**提示:**如果列名称包含空格,要求使用双引号或方括号:
在使用H5混合开发的app打包后,需要将ipa文件上传到appstore进行发布,就需要去苹果开发者中心进行发布。​
+----+--------------+---------------------------+-------+---------+
数组的声明并不是声明一个个单独的变量,比如 number0、number1、...、number99,而是声明一个数组变量,比如 numbers,然后使用 nu...
第一步:到appuploader官网下载辅助工具和iCloud驱动,使用前面创建的AppID登录。
如需删除表中的列,请使用下面的语法(请注意,某些数据库系统不允许这种在数据库表中删除列的方式):
前不久在制作win11pe,制作了一版,1.26GB,太大了,不满意,想再裁剪下,发现这次dism mount正常,commit或discard巨慢,以前都很快...
赛门铁克各个版本概览:https://knowledge.broadcom.com/external/article?legacyId=tech163829
实测Python 3.6.6用pip 21.3.1,再高就报错了,Python 3.10.7用pip 22.3.1是可以的
Broadcom Corporation (博通公司,股票代号AVGO)是全球领先的有线和无线通信半导体公司。其产品实现向家庭、 办公室和移动环境以及在这些环境...
发现个问题,server2016上安装了c4d这些版本,低版本的正常显示窗格,但红色圈出的高版本c4d打开后不显示窗格,
TAT:https://cloud.tencent.com/document/product/1340