一、什么是Catalina?

Catalina包含了前面讲到的所有的容器组件,以及后面会涉及到的安全、会话、集群、部署、管理等Servlet容器架构的各个方面。他通过松耦合的方式集成Coyote,以完成按照请求协议进行数据读写。同时,他还包括我们的启动入口、Shell程序等。
    如果以一个简单的模块依赖图来描述Catalina在整个Tomcat中的位置,那么如下图所示:

    Tomcat本质上是一款Serlet容器,因此Catalina是Tomcat的核心,其他模块均为Catalina提供支撑。通过Coyote模块提供链接通信,Jasper模块提供JSP引擎,Naming提供JNDI服务,Juli提供日志服务。

二、Digester

根据前面的讲述可知,Catalina使用Digester解析XML(server.xml)配置文件并且创建应用服务器。因此,在讲解Catalina之前,有必要先介绍一个Digester,这有利于了解Catalina的创建过程,因为Tomcat在Catalina的创建过程中通过Digester结合LifecycleListener做了大量的初始化工作。如果不熟悉Digester,将很难理解Catalina的创建过程。

Digester是一款用于将XML转化为Java对象的事件驱动工具,是对SAX的高层次的封装。Digester针对SAX事件提供了更加友好的接口,隐藏了XML节点具体的层次细节,使得开发者可以更加专注于处理过程。

DIgester以及SAX的事件驱动,简而言之,就是通过流读取XML文件,当识别出特定的XMKL节点后便会执行特定的动作,或者创建Java对象,或者执行对象的某个方法。因此Digester的核心是匹配模式和处理规则。

1、对象栈

Digester的对象栈主要是在匹配模式满足是,由处理规则进行操作。他提供了常见的栈操作:

  • clear:清空对象栈。
  • peek:该操作有数个重载方法,可以实现得到位于栈顶部的对象或者从顶部数第n个对象,但是不会将对象从栈中移除。
  • pop:将位于栈顶部的对象移除并且返回。
  • push:将对象放到栈顶部。

Digester的设计模式是指,在文件读取过程中,如果遇到一个XML节点的开始部分,则会出发处理规则事件创建Java对象,并且将其放入栈中。当处理该节点的时候,该对象都将维护在栈中。当遇到该节点的结束部分时候,该对象将会从栈中取出并且清除。

当然,这种设计模式需要解决几个问题,这些问题以及Digester的解决方案如下:

  • 如何在创建对象之间建立关联?最终得到的结果应该是一个分层次的Java对象树。Digester提供了一个处理规则实现(SetNexRule),该规则会调用位于栈顶部对象之后对象的某个方法,同时将顶部对象作为参数传入。通过此方法可以很容易在XML各Java对象之间建立父子关系,无论是一对一还是一对多的关系。
  • 如何持有创建的首个对象,即XML的转换结果?从上面的对象创建过程得知,当XML转换结束的时候,由于遇到了XML节点的借宿部分,兑现将从栈中移除。Digester对于曾经放入栈中的第一个对象将会持有一个引用,同时作为parse()方法的返回值。还有一种方式,可以在调用parse()方法之前,传入一个已经创建的对象的引用,Digester会动态的为这个对象和首个创建的对象建立父子关系。通过这种方式,传入的对象将会维护首个创建对象的引用以及所有子节点,当然传入对象也会在调用parse()方法时返回。Tomcat创建Servlet容器时采用后者。

2、匹配模式

Digester的主要特征是自动遍历XML文档,而使得开发者不必关注解析过程。与之对应,需要确定当读取到某个约定的XML节点时候需要执行何种操作。Digester通过匹配模式指定相关约定。

Digester的匹配模式如下表所示:

匹配模式 XML节点 描述
a 匹配所有名字为"a"的根节点,注意嵌套的同名子节点无法匹配
a/b 匹配所有父节点为根节点“a”的名称为"b"的节点

当然,匹配模式还支持模糊匹配,如果我们希望所有系欸但都采用同一个处理规则,那么直接制定匹配规则为“ /* ”即可,我们还可以指定 “ */b ”来处理所有的名称为“ b ”的节点,而不限制其参差或者上级节点的名称。

当同一个匹配模式指定多个处理规则,或者多个匹配规则匹配同一个节点的时候,均会出现一个节点执行多个处理规则的情况。此时,Digester的处理方式是,开始读取节点时按照注册顺序执行处理规则,而完成读取时按照方向顺序执行,即先进后出的规则。

3、处理规则

匹配模式确定了何时触发处理操作,而处理规则定义了模式匹配时的具体操作。处理规则需要实现接口org.apache.commins.digester.Rule,该接口定义了模式匹配时出发的事件方法。

  • begin():当读取到匹配节点的开始部分调用,会将该节点的所有属性作为参数传入。
  • body():当读取到匹配节点的内容时调用,注意指的并不是子节点,而是嵌入内容为普通文本。
  • end():当读取到匹配节点的借宿部分时调用,如果存在子节点,只有当子节点处理完毕后该方法才会被调用。
  • finish():当整个parse()方法完成时调用,多余清除临时数据和缓存数据。

我们可以通过Gigester类的addRule()方法为某个匹配模式指定一个处理规则,同时可以根据需要实现自己的规则。针对大多数常见的场景,Digester为我们提供了默认的处理规则实现类。

Digester默认支持的处理规则如下图所示:

三、总结

Digester提供了一套对象栈机制用于构造Java对象,这是因为XML是分层结构,所以我们创建的Java对象也应该是分层的树状结构,而且还要根据XML内容组织各层级Java对象的内部结构以及设置相关属性。最后需要注意的是,Digester是非线程安全的。

Tomcat架构解析之Digester相关推荐

  1. Tomcat架构解析之3 Connector NIO

    上文简单记录了默认的Connector的内部构造及消息流,同时此Connector也是基于BIO的实现. 除BIO,也可以通过配置快速部署NIO的connector.在server.xml中如下配置: ...

  2. Tomcat架构解析之AJP

    一.前言 除了HTTP,Tomcat还支持AJP协议,以便于Apache HTTP Server等Web服务器集成,这篇博客主要讲解AJP协议的基础知识以及其配置使用方式. 二.基础知识 为了满足负载 ...

  3. Tomcat架构解析之DefaultServlet和JspServlet

    一.前言 Tomcat在$ CATALINA_BASE/conf/web.xml中默认定义了两个Servlet:DefaultServlet和JspServlet,而且由于$ CATALINA_BAS ...

  4. Tomcat架构解析之HTTP/2.0

    一.前言 自8.5版本开始,Tomcat增加了对HTTP/2.0的支持.在这篇博客中,我们将简单介绍HTTP/2.0的发展.基本知识以及其配置使用方式. 二.基础知识 谈到HTTP/2.0,就不得不先 ...

  5. Tomcat架构浅析

    Tomcat服务器作为目前比较流行的一种服务器容器已经被广泛用于后台服务器的搭建.后台集成框架的嵌入(如SpringBoot),不同于Apache.Nginx本身(注意是本身,其实可以搭配后台脚本实现 ...

  6. tomcat源码之架构解析

    1. Tomcat的整体框架结构   Tomcat的基本框架, 分为4个层次.   Top Level Elements:    Server    Service       Connector   ...

  7. Tomcat 架构原理解析到架构设计借鉴

    ‍ 点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 Tomcat 架构原理解析到架构设计借鉴 Tomcat 发展这 ...

  8. 【Tomcat 】Tomcat 架构原理解析到架构设计借鉴

    Tomcat 发展这么多年,已经比较成熟稳定.在如今『追新求快』的时代,Tomcat 作为 Java Web 开发必备的工具似乎变成了『熟悉的陌生人』,难道说如今就没有必要深入学习它了么?学习它我们又 ...

  9. Tomcat学习之Tomcat架构

    前段时间想学习下tomcat,在网上找了一些资料,放在这里以备忘: 1,tomcat架构: Server: 其实就是BackGroud程序, 在Tomcat里面的Server的用处是启动和监听服务端事 ...

  10. tomcat架构分析 (Session管理)【转】

    原文地址:https://www.iteye.com/blog/gearever-1546423 Session管理是JavaEE容器比较重要的一部分,在app中也经常会用到.在开发app时,我们只是 ...

最新文章

  1. Linux下查找文件方法
  2. 模拟电子技术_清华大学华成英教授主讲之符号说明
  3. word 2010中如何创建多级目录和多级列表
  4. 解决修改/etc/sudoers文件后:报 语法错误 near line 23
  5. 车联网大数据框架_FEV:基于最新网关技术管理车联网大数据
  6. 为什么java抗并发_用最通熟易懂的话说明,为什么要使用java并发编程
  7. 启动FastDFS服务,使用python客户端对接fastdfs完成上传测试
  8. 从一套表达和通路数据学习常见的绘图展示方式和报错处理
  9. 3倍根号x加1分之一c语言,用C语言将一个数开根号后再取倒数的方法
  10. html5-svg和Two.js的使用方法(附案例)
  11. 计算机网络的带宽是指网络可通过的,计算机网络及带宽概念.ppt
  12. 让Kubernetes成为数据中心操作系统(DCOS)的一等公民
  13. [转载] Python ascii()函数
  14. 用于登录的mysql语句_mysql常用语句
  15. vs2010 sp1安装
  16. 软件测试肖sir___项目讲解之银行项目
  17. 免费自媒体全网平台爆文采集器
  18. C++中的内存管理、内存泄漏和内存回收
  19. redis常见问题及解决方案
  20. kaggle糖尿病视网膜病变失明检测top5解决方案

热门文章

  1. 关于pthread_cancel()的运用,取消点的理解
  2. Web测试需要注意的点
  3. Python机器学习:基于西瓜数据集的KNN算法实现
  4. 联想笔记本电脑换掉原装系统后无法进BIOS不完美解决办法
  5. STM32F4xx固件库分析
  6. DCDC Bootstrap自举电路
  7. pci-e服务器显卡性能,PCI-E插槽速度可影响游戏性能
  8. 01 Python pikepdf 解锁带有密码的PDF文件
  9. WiFi相关知识介绍
  10. 滑动窗口协议如何实现流量控制