来源

本文整理自 <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. idea快捷键、常用设置

      代码提示: code completion :ALT + / 选用Eclipse的keymap. 设置代码助手快捷键(keymap-basic) 代码上下行复制(Ctrl + Alt + Down ...

  2. input的属性用法介绍

    Input表示Form表单中的一种输入对象,其又随Type类型的不同而分文本输入框,密码输入框,单选/复选框,提交/重置按钮等,下面一一介绍. 1,type=text 输入类型是text,这是我们见的 ...

  3. Java-----思想认识

    1.1 Java封装性思想的初步理解 从项目需求的角度出发,建立各个模块化的类,各个模块暂时不需要具体的方法描述,只需要各个模块的理想到位. 以银行项目为例.初步设想需要三个模块:银行(Bank类). ...

  4. Iphone各个型号机型的详细参数,尺寸和dpr以及像素

    1.iPhone尺寸规格 2.单位inch(英吋) 1 inch = 2.54cm = 25.4mm 3.iPhone手机宽高 上表中的宽高(width/height)为手机的物理尺寸,包括显示屏和边 ...

  5. git版本控制的使用

    特别说明:本文所有知识笔记是学习“表严肃”同学的git课程记录所得. 前辈个人网站地址:http://biaoyansu.com 特此感谢前辈! 一.git是版本控制利器 二.本地创建仓库 1.进入新 ...

  6. laravel验证码

    登录验证码 1.首先,进入https://github.com/mewebstudio/captcha,根据captcha上的使用方法一步步来实现验证码的安装,因为是laravel5.7,所以选择了c ...

  7. Java链接 Oracle11g R2

    菜鸟学习Oracle数据库,使用Java代码链接数据库. 首先要配置Eclipse,在新建的工程中,Package Explorer->工程名->Build path->Add ex ...

  8. Python 练习项目1 弹球游戏

    这几天学习了python的基础知识,然后参考了网上的一些资料,完成了一个自己的小游戏,弹球游戏比较简单,但却具备了一些游戏的普遍特征,对于初学者是一个比较合适的锻炼的项目. 下面是效果图: 完整程序: ...

  9. <meta name="renderer" content="webkit">

    <meta name="renderer" content="webkit"> 当前国内的大部分主流浏览器(如360)基本都是双核浏览器,所谓双核即 ...

  10. Redux学习笔记-基础知识

      Redux概述 是什么:Redux是管理状态的容器,提供可预测的状态管理. 怎么做:Redux主要是用来管理组件或者应用的状态,本质上跟一个事件处理器差不多.通过分发action触发reduce来 ...