Server.xml解析

来源

本文整理自 <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");

猜你喜欢

转载自www.cnblogs.com/wansw/p/10238526.html