来源

本文整理自 <Tomcat内核设计剖析>、<Tomcat结构解析> 加上自己的理解、源码来自 Tomcat8.5 版本
<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" /> <GlobalNamingResources>
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml" />
</GlobalNamingResources> <Service name="Catalina"> <Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" /> <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> <Engine name="Catalina" defaultHost="localhost"> <Realm className="org.apache.catalina.realm.LockOutRealm">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
</Realm> <Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true"> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t &quot;%r&quot; %s %b" /> </Host>
</Engine>
</Service>
</Server>
// org.apache.catalina.startup.Catalina.java
public void load() {
digester.parse(inputSource);
}

​ Catalina使用Digester解析XML配置文件并创建应用服务器。

​ Digester是一款用于将XML转化成Java对象的事件驱动型工具,针对SAX的进一步封装。Digester对SAX事件提供了更加友好的接口,隐藏了XML节点具体的层次细节。目前是Apache Commons项目。

​ Digester通过流读取XML文件,当识别出特定XML节点后便会执行特定的动作、或者创建Java对象,或者执行对象的某个方法。核心是:匹配模式和处理规则。

​ Digester是非线程安全的。

Server解析

创建Server实例

​ Catalina中Server默认实现 StandardServer、Digester创建Server实例后,设置Server相关属性,并将其设置到Catalina对象中(调用setServer)

digester.addObjectCreate("Server",
"org.apache.catalina.core.StandardServer",
"className");
digester.addSetProperties("Server");
digester.addSetNext("Server",
"setServer",
"org.apache.catalina.Server");

创建全局命名资源

​ Catalina根据GlobalNamingResources配置创建全局的命名资源上下文(JNDI),设置属性并将其设置到Server实例中(setGlobalNamingResources)

digester.addObjectCreate("Server/GlobalNamingResources",
"org.apache.catalina.deploy.NamingResourcesImpl");
digester.addSetProperties("Server/GlobalNamingResources");
digester.addSetNext("Server/GlobalNamingResources",
"setGlobalNamingResources",
"org.apache.catalina.deploy.NamingResourcesImpl");

Server添加生命周期监听器

​ Server元素支持配置Listener节点,用于为当前的Server实例添加LifecycleListener监听器,由classNmae属性指定,默认配置了5个监听器:

digester.addObjectCreate("Server/Listener",
null, // MUST be specified in the element
"className");
digester.addSetProperties("Server/Listener");
digester.addSetNext("Server/Listener",
"addLifecycleListener",
"org.apache.catalina.LifecycleListener"); digester.addObjectCreate("Server/Service",
"org.apache.catalina.core.StandardService",
"className");
digester.addSetProperties("Server/Service");
digester.addSetNext("Server/Service",
"addService",
"org.apache.catalina.Service");

创建Service实例

​ Server添加Service实例,Catalina默认的Service实例是 StandardServie,可以通过addService()添加到Server实例中。

digester.addObjectCreate("Server/Service",
"org.apache.catalina.core.StandardService",
"className");
digester.addSetProperties("Server/Service");
digester.addSetNext("Server/Service",
"addService",
"org.apache.catalina.Service");

Service添加生命周期监听器

​ 由className 属性指定,默认未指定Service监听器。

digester.addObjectCreate("Server/Service/Listener",
null, // MUST be specified in the element
"className");
digester.addSetProperties("Server/Service/Listener");
digester.addSetNext("Server/Service/Listener",
"addLifecycleListener",
"org.apache.catalina.LifecycleListener");

Service添加Executor

​ 默认实现StandardThreadExecutor,由className属性指定具体实现类,Catalina共享Executor的级别是Service。默认未配置

digester.addObjectCreate("Server/Service/Executor",
"org.apache.catalina.core.StandardThreadExecutor",
"className");
digester.addSetProperties("Server/Service/Executor"); digester.addSetNext("Server/Service/Executor",
"addExecutor",
"org.apache.catalina.Executor");

Service添加Connector

​ 在设置属性时,将executor和sslImplementationName属性排除。在Connector创建时,会判断当前是否指定了executor属性,如果是,从Service中查找该名称的executor并设置到Connector中。在创建Connector时也会判断是否有sslImplementationName属性,如果是,将属性设置到使用的协议中,指定了一个SSL实现。

digester.addRule("Server/Service/Connector",
new ConnectorCreateRule());
digester.addRule("Server/Service/Connector",
new SetAllPropertiesRule(new String[]{"executor", "sslImplementationName"}));
digester.addSetNext("Server/Service/Connector",
"addConnector",
"org.apache.catalina.connector.Connector");

Connector添加虚拟主机SSL配置

digester.addObjectCreate("Server/Service/Connector/SSLHostConfig",
"org.apache.tomcat.util.net.SSLHostConfig");
digester.addSetProperties("Server/Service/Connector/SSLHostConfig");
digester.addSetNext("Server/Service/Connector/SSLHostConfig",
"addSslHostConfig",
"org.apache.tomcat.util.net.SSLHostConfig");
digester.addRule("Server/Service/Connector/SSLHostConfig/Certificate",
new CertificateCreateRule());
digester.addRule("Server/Service/Connector/SSLHostConfig/Certificate",
new SetAllPropertiesRule(new String[]{"type"}));
digester.addSetNext("Server/Service/Connector/SSLHostConfig/Certificate",
"addCertificate",
"org.apache.tomcat.util.net.SSLHostConfigCertificate");

Connector添加生命周期监听器

​ 默认情况下,未指定。

digester.addObjectCreate("Server/Service/Connector/Listener",
null, // MUST be specified in the element
"className");
digester.addSetProperties("Server/Service/Connector/Listener");
digester.addSetNext("Server/Service/Connector/Listener",
"addLifecycleListener",
"org.apache.catalina.LifecycleListener");

Connector添加升级协议

​ 用于支持HTTP/2,8.5.6新增的配置。

digester.addObjectCreate("Server/Service/Connector/UpgradeProtocol",
null, // MUST be specified in the element
"className");
digester.addSetProperties("Server/Service/Connector/UpgradeProtocol");
digester.addSetNext("Server/Service/Connector/UpgradeProtocol",
"addUpgradeProtocol",
"org.apache.coyote.UpgradeProtocol");

子元素解析规则

​ 指定了Servlet容器相关的嵌套子节点的解析规则,而且每类嵌套子节点的解析封装为一个RuleSet,包含

GlobalNamingResource、Engine、Host、Cluster、Context

digester.addRuleSet(new NamingRuleSet("Server/GlobalNamingResources/"));
digester.addRuleSet(new EngineRuleSet("Server/Service/"));
digester.addRuleSet(new HostRuleSet("Server/Service/Engine/"));
digester.addRuleSet(new ContextRuleSet("Server/Service/Engine/Host/"));
addClusterRuleSet(digester, "Server/Service/Engine/Host/Cluster/");
digester.addRuleSet(new NamingRuleSet("Server/Service/Engine/Host/Context/"));
digester.addRule("Server/Service/Engine",
new SetParentClassLoaderRule(parentClassLoader));
addClusterRuleSet(digester, "Server/Service/Engine/Cluster/");

Engine解析

​ 在EngineRuleSet类下,创建Engine实例,并通过setContainer方法添加到Service实例,Catalina默认实现为StandardEngine。默认为Engine添加了一个生命周期监听器 EngineConfig。(用于打印Engine启动和停止日志)

digester.addObjectCreate(prefix + "Engine",
"org.apache.catalina.core.StandardEngine",
"className");
digester.addSetProperties(prefix + "Engine");
digester.addRule(prefix + "Engine",
new LifecycleListenerRule
("org.apache.catalina.startup.EngineConfig",
"engineConfigClass"));
digester.addSetNext(prefix + "Engine",
"setContainer",
"org.apache.catalina.Engine");

Engine添加集群配置

digester.addObjectCreate(prefix + "Engine/Cluster",
null, // MUST be specified in the element
"className");
digester.addSetProperties(prefix + "Engine/Cluster");
digester.addSetNext(prefix + "Engine/Cluster",
"setCluster",
"org.apache.catalina.Cluster");

Engine添加生命周期监听器

​ 此处与EngineConfig不同,这里由server.xml 配置。默认未指定。

digester.addObjectCreate(prefix + "Engine/Listener",
null, // MUST be specified in the element
"className");
digester.addSetProperties(prefix + "Engine/Listener");
digester.addSetNext(prefix + "Engine/Listener",
"addLifecycleListener",
"org.apache.catalina.LifecycleListener");

Engine添加安全配置和Valve

​ 为Engine添加安全配置(RealmRuleSet),添加Valve拦截器。

digester.addObjectCreate(pattern, null /* MUST be specified in the element */,
"className");
digester.addSetProperties(pattern);
digester.addSetNext(pattern, methodName, "org.apache.catalina.Realm");
digester.addRuleSet(new CredentialHandlerRuleSet(pattern + "/")); digester.addObjectCreate(prefix + "Engine/Valve",
null, // MUST be specified in the element
"className");
digester.addSetProperties(prefix + "Engine/Valve");
digester.addSetNext(prefix + "Engine/Valve",
"addValve",
"org.apache.catalina.Valve");

Host的解析

创建Host实例

​ 位于HostRuleSet类中。创建Host实例,通过addChild方法添加到Engine中,Catalina默认实现 StandardHost,同时注册了一个生命周期监听器 HostConfig,该监听器在 Web应用部署中做了大量工作,同时Host还可以通过 Alias 支持配置 别名

digester.addObjectCreate(prefix + "Host",
"org.apache.catalina.core.StandardHost",
"className");
digester.addSetProperties(prefix + "Host");
digester.addRule(prefix + "Host",
new CopyParentClassLoaderRule());
digester.addRule(prefix + "Host",
new LifecycleListenerRule
("org.apache.catalina.startup.HostConfig",
"hostConfigClass"));
digester.addSetNext(prefix + "Host",
"addChild",
"org.apache.catalina.Container"); digester.addCallMethod(prefix + "Host/Alias",
"addAlias", 0);

Host添加集群

​ Cluster可以配置在 Engine ,还可以配置在Engine级别。

digester.addObjectCreate(prefix + "Host/Cluster",
null, // MUST be specified in the element
"className");
digester.addSetProperties(prefix + "Host/Cluster");
digester.addSetNext(prefix + "Host/Cluster",
"setCluster",
"org.apache.catalina.Cluster");

Host添加生命周期监听器

​ 此配置由 server.xml 配置,默认;无

digester.addObjectCreate(prefix + "Host/Listener",
null, // MUST be specified in the element
"className");
digester.addSetProperties(prefix + "Host/Listener");
digester.addSetNext(prefix + "Host/Listener",
"addLifecycleListener",
"org.apache.catalina.LifecycleListener");

Host添加安全配置和Valve

​ Valve默认是 AccessLogValve。用于记录访问日志。

digester.addObjectCreate(pattern, null /* MUST be specified in the element */,
"className");
digester.addSetProperties(pattern);
digester.addSetNext(pattern, methodName, "org.apache.catalina.Realm");
digester.addRuleSet(new CredentialHandlerRuleSet(pattern + "/")); digester.addObjectCreate(prefix + "Host/Valve",
null, // MUST be specified in the element
"className");
digester.addSetProperties(prefix + "Host/Valve");
digester.addSetNext(prefix + "Host/Valve",
"addValve",
"org.apache.catalina.Valve");

Context解析

​ 这里对的Context配置,仅仅指 server.xml 中配置,默认情况下,在server.xml 中不配置。通过 HostConfig 自动扫描部署目录,以 context.xml 文件为基础进行解析创建。

创建Context实例

​ 位于ContextRuleSet类中。create==true时,创建Context实例,通过 HostConfig 自动创建Context时,create=false,默认实现类是 StandardContext。在创建实例时,添加了一个生命周期监听器 ContextConfig,用于详细配置 Context,如解析 web.xml 等。

if (create) {
digester.addObjectCreate(prefix + "Context",
"org.apache.catalina.core.StandardContext", "className");
digester.addSetProperties(prefix + "Context");
} else {
digester.addRule(prefix + "Context", new SetContextPropertiesRule());
} if (create) {
digester.addRule(prefix + "Context",
new LifecycleListenerRule
("org.apache.catalina.startup.ContextConfig",
"configClass"));
digester.addSetNext(prefix + "Context",
"addChild",
"org.apache.catalina.Container");
}

Context添加生命周期监听器

​ 此配置由 server.xml 配置,默认;无

digester.addObjectCreate(prefix + "Context/Listener",
null, // MUST be specified in the element
"className");
digester.addSetProperties(prefix + "Context/Listener");
digester.addSetNext(prefix + "Context/Listener",
"addLifecycleListener",
"org.apache.catalina.LifecycleListener");

Context指定类加载器

​ 默认 WebappLoader。

digester.addObjectCreate(prefix + "Context/Loader",
"org.apache.catalina.loader.WebappLoader",
"className");
digester.addSetProperties(prefix + "Context/Loader");
digester.addSetNext(prefix + "Context/Loader",
"setLoader",
"org.apache.catalina.Loader");

Context添加会话管理器

​ 默认是:StandardManager,同时为管理器指定了会话存储方式和会话标识生成器。

digester.addObjectCreate(prefix + "Context/Manager",
"org.apache.catalina.session.StandardManager",
"className");
digester.addSetProperties(prefix + "Context/Manager");
digester.addSetNext(prefix + "Context/Manager",
"setManager",
"org.apache.catalina.Manager"); digester.addObjectCreate(prefix + "Context/Manager/Store",
null, // MUST be specified in the element
"className");
digester.addSetProperties(prefix + "Context/Manager/Store");
digester.addSetNext(prefix + "Context/Manager/Store",
"setStore",
"org.apache.catalina.Store"); digester.addObjectCreate(prefix + "Context/Manager/SessionIdGenerator",
"org.apache.catalina.util.StandardSessionIdGenerator",
"className");
digester.addSetProperties(prefix + "Context/Manager/SessionIdGenerator");
digester.addSetNext(prefix + "Context/Manager/SessionIdGenerator",
"setSessionIdGenerator",
"org.apache.catalina.SessionIdGenerator");

Context添加初始化参数

digester.addObjectCreate(prefix + "Context/Parameter",
"org.apache.tomcat.util.descriptor.web.ApplicationParameter");
digester.addSetProperties(prefix + "Context/Parameter");
digester.addSetNext(prefix + "Context/Parameter",
"addApplicationParameter",
"org.apache.tomcat.util.descriptor.web.ApplicationParameter");

Context添加安全配置和Web资源配置

​ Tomcat8中新增了 PreResources、JarResources、PostResources三种资源的配置。在加载Web应用时使用。

digester.addRuleSet(new RealmRuleSet(prefix + "Context/"));
digester.addObjectCreate(prefix + "Context/Resources",
"org.apache.catalina.webresources.StandardRoot",
"className");
digester.addSetProperties(prefix + "Context/Resources");
digester.addSetNext(prefix + "Context/Resources",
"setResources",
"org.apache.catalina.WebResourceRoot");
digester.addObjectCreate(prefix + "Context/Resources/PreResources",
null, // MUST be specified in the element
"className");
digester.addSetProperties(prefix + "Context/Resources/PreResources");
digester.addSetNext(prefix + "Context/Resources/PreResources",
"addPreResources",
"org.apache.catalina.WebResourceSet");
digester.addObjectCreate(prefix + "Context/Resources/JarResources",
null, // MUST be specified in the element
"className");
digester.addSetProperties(prefix + "Context/Resources/JarResources");
digester.addSetNext(prefix + "Context/Resources/JarResources",
"addJarResources",
"org.apache.catalina.WebResourceSet");
digester.addObjectCreate(prefix + "Context/Resources/PostResources",
null, // MUST be specified in the element
"className");
digester.addSetProperties(prefix + "Context/Resources/PostResources");
digester.addSetNext(prefix + "Context/Resources/PostResources",
"addPostResources",
"org.apache.catalina.WebResourceSet");

Context添加资源链接

​ 添加 ContextResourceLink,用于J2EE命名服务(JNDI)

digester.addObjectCreate(prefix + "Context/ResourceLink",
"org.apache.tomcat.util.descriptor.web.ContextResourceLink");
digester.addSetProperties(prefix + "Context/ResourceLink");
digester.addRule(prefix + "Context/ResourceLink",
new SetNextNamingRule("addResourceLink", "org.apache.tomcat.util.descriptor.web.ContextResourceLink"));

Context添加Valve

digester.addObjectCreate(prefix + "Context/Valve",
null, // MUST be specified in the element
"className");
digester.addSetProperties(prefix + "Context/Valve");
digester.addSetNext(prefix + "Context/Valve",
"addValve",
"org.apache.catalina.Valve");

Context添加守护资源配置

​ WatchedResource:用于为Context添加监视资源,当这些资源发生变更时,Web应用会被重新加载。默认值:/WEB-INF/web.xml。 在 conf/context.xml 中配置。

​ WrapperLifecycle:为Context添加一个监听器类,添加到Context 包含的 Wrapper 上。

​ JarScanner:默认实现是 StandardJarScanner。StandardJarScanner 扫描Web应用和类加载器层级的Jar包,主要用于TLD扫描和web-fragement.xml扫描。还可以为 JarScanner 指定一个Filter,只有符合的才会被处理。默认Filter:StandardJarScanFilter。

digester.addCallMethod(prefix + "Context/WatchedResource",
"addWatchedResource", 0); digester.addCallMethod(prefix + "Context/WrapperLifecycle",
"addWrapperLifecycle", 0); digester.addCallMethod(prefix + "Context/WrapperListener",
"addWrapperListener", 0); digester.addObjectCreate(prefix + "Context/JarScanner",
"org.apache.tomcat.util.scan.StandardJarScanner",
"className");
digester.addSetProperties(prefix + "Context/JarScanner");
digester.addSetNext(prefix + "Context/JarScanner",
"setJarScanner",
"org.apache.tomcat.JarScanner"); digester.addObjectCreate(prefix + "Context/JarScanner/JarScanFilter",
"org.apache.tomcat.util.scan.StandardJarScanFilter",
"className");
digester.addSetProperties(prefix + "Context/JarScanner/JarScanFilter");
digester.addSetNext(prefix + "Context/JarScanner/JarScanFilter",
"setJarScanFilter",
"org.apache.tomcat.JarScanFilter");

Context添加Cookie处理器

​ Tomcat8.5版本从 LegacyCookieProcessor 改成 Rfc6265CookieProcessor。

digester.addObjectCreate(prefix + "Context/CookieProcessor",
"org.apache.tomcat.util.http.Rfc6265CookieProcessor",
"className");
digester.addSetProperties(prefix + "Context/CookieProcessor");
digester.addSetNext(prefix + "Context/CookieProcessor",
"setCookieProcessor",
"org.apache.tomcat.util.http.CookieProcessor");

Server.xml解析的更多相关文章

  1. server.xml 解析

    server.xml的结构: 常用配置的参数注释: <?xml version='1.0' encoding='utf-8'?> <!-- Licensed to the Apach ...

  2. Tomcat的配置文件Server.xml解析

    配置元素说明: 元素名 属性 解释 server port 指定一个端口,这个端口负责监听关闭tomcat 的请求 shutdown 指定向端口发送的命令字符串 service name 指定serv ...

  3. Tomcat配置文件之“server.xml”解析

    <?xml version="1.0" encoding="UTF-8"?> <!--代表整个Servlet容器组件,是最顶层元素.它里面可以 ...

  4. Tomcat源码分析——SERVER.XML文件的加载与解析

    前言 作为Java程序员,对于Tomcat的server.xml想必都不陌生.本文基于Tomcat7.0的Java源码,对server.xml文件是如何加载和解析的进行分析. 加载 server.xm ...

  5. SQL Server XML数据解析

    --5.读取XML --下面为多种方法从XML中读取EMAIL DECLARE @x XML SELECT @x = ' <People> <dongsheng> <In ...

  6. Tomcat 利用server.xml进行其他盘符的其他项目映射的部署以及JSP引用其他盘符的图片(虚拟目录及虚拟路径)

    Tomcat 利用server.xml进行项目映射的部署 2013-07-17 15:14 12843人阅读 评论(4) 收藏 举报  分类: web 开发(5)  版权声明:本文为博主原创文章,欢迎 ...

  7. Tomcat的目录结构、处理流程、主配置文件(server.xml)释义

    参考资料: http://www.cnblogs.com/xdp-gacl/p/3744053.html http://grass51.blog.51cto.com/4356355/1123400 1 ...

  8. Tomcat配置文件server.xml

    Tomcat目录中的server.xml配置文件 server.xml称为主配置文件或全局配置文件 它完成以下两个目标: 1,提供Tomcat组件的初始化配置 2,说明Tomcat的结构和含义,使得T ...

  9. Tomcat server.xml详解

    Server.xml的结构大致 <Server port="8005" shutdown="SHUTDOWN"> <Service name= ...

随机推荐

  1. Vue引入第三方JavaScript库和如何创建自己的Vue插件

    一 第三方JavaScript库 前言 .vue文件 中不解析 script标签引入js文件,只能用 import 引入 有两种用法: 1.import a from '../a' 2.import ...

  2. K2P刷机教程转自恩山磨人的小妖精

    K2P刷机指南说明 K2P MTK版发布之初用的是22.5.7.85, 这个版本官改和高恪K2P固件都可以从斐讯固件基础上直接升级, 是所谓直刷.但好景不长, 之后的版本比如22.5.17.33就改了 ...

  3. 00HTML

    一.概述 超文本标记语言(Hyper Text Markup Language),HTML是一门描述性的语言.基本语法: <标签> 内容 </标签>** 在一个网页中,HTML ...

  4. 【Android】10.0 UI开发——如何编写程序界面、常见控件的使用

    ************************ 转载请注明出处:https://www.cnblogs.com/xiaofu007/p/10331880.html ***************** ...

  5. sql中replace的用法

    update 表名 set 字段名=REPLACE (字段名,'原来的值','要修改的值') 如:将tbl_user表的user_name字段中的大写的A替换成小写的a update tbl_stud ...

  6. hiho 1015 KMP算法 && CF 625 B. War of the Corporations

    #1015 : KMP算法 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在 ...

  7. 创建线程后马上CloseHandle(threadhandle)起什么作用

    原文:http://www.cnblogs.com/eddyshn/archive/2010/04/14/1711674.html HANDLE threadhandle = CreateThread ...

  8. C++模板详解(系转载,但是个人添加了一些内容)

    原文地址:http://www.cnblogs.com/gw811/archive/2012/10/25/2738929.html 零.概述 模板是C++支持参数化多态的工具,使用模板可以使用户为类或 ...

  9. 深入理解token

      链接:https://my.oschina.net/jamesfancy/blog/1613994 摘要: Token 是在服务端产生的.如果前端使用用户名/密码向服务端请求认证,服务端认证成功, ...

  10. 针对XX系统的可用性方面的相关想法(结合书)

    在开始对此系统进行再次分析之前,再回顾下可用性.首先,可用性是与系统故障有关的一个质量属性,是指系统正常运行的时间的比例,一般通过两次故障之间的时间长度或在系统崩溃情况下能恢复正常运行的速度来衡量,同 ...