Tomcat load方法窥探
Posted logan12138
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Tomcat load方法窥探相关的知识,希望对你有一定的参考价值。
在Catalina启动之前,会先调用load方法,并在启动时校验load方法是否执行成功。
load
// Create and execute our Digester Digester digester = createStartDigester(); try (ConfigurationSource.Resource resource = ConfigFileLoader.getSource().getServerXml()) { InputStream inputStream = resource.getInputStream(); InputSource inputSource = new InputSource(resource.getURI().toURL().toString()); inputSource.setByteStream(inputStream); digester.push(this); digester.parse(inputSource); } catch (Exception e) { log.warn(sm.getString("catalina.configFail", file.getAbsolutePath()), e); if (file.exists() && !file.canRead()) { log.warn(sm.getString("catalina.incorrectPermissions")); } return; }
这段code会解析config/server.xml。解析完成后,Catalina里的Server如下图。
打开Server里的services如下图。
再看看service里的4个容器。
这些构造都是依据server.xml里的配置,以及创建Degister时在代码里添加的RuleSet。
// Add RuleSets for nested elements 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/"));
然后,则会调用Server的 init 方法。
init @ StandardServer
刨去java security和JNDI的代码,Server的 init 将 commonLoader 挂在了SystemClassLoader 下,并调用了Service的 init 方法。
// Populate the extension validator with JARs from common and shared // class loaders if (getCatalina() != null) { ClassLoader cl = getCatalina().getParentClassLoader(); // Walk the class loader hierarchy. Stop at the system class loader. // This will add the shared (if present) and common class loaders while (cl != null && cl != ClassLoader.getSystemClassLoader()) { if (cl instanceof URLClassLoader) { URL[] urls = ((URLClassLoader) cl).getURLs(); for (URL url : urls) { if (url.getProtocol().equals("file")) { try { File f = new File (url.toURI()); if (f.isFile() && f.getName().endsWith(".jar")) { ExtensionValidator.addSystemResource(f); } } catch (URISyntaxException e) { // Ignore } catch (IOException e) { // Ignore } } } } cl = cl.getParent(); } }
然后,在for循环里 init Service。
init @ StandardService
Service 的 init 调用了其引用的Engine、mapperListener和connector的init方法。
其中mapperListener负责的是 uri 到最终的 Wrapper 的添加、移除和解析等。
Connector的 init 则是调用ProtocolHandler(如果在server.xml配置的http的Connector,则这里指的是Http11NioProtocol)的 init,ProtocolHandler的init则调用了AbstractEndpoint(如果在server.xml配置的http的Connector,则这里指的是NioEndpoint)的init。endPoint的init则进行了ServerSocket的端口绑定等工作。
init @ StandardEngine
Engine的init除了JNDI外没有做什么。
Engine的Listener -- EngineConfig在这里也没有做什么。
以上是关于Tomcat load方法窥探的主要内容,如果未能解决你的问题,请参考以下文章
jsp页面被tomcat引擎运行的时候组装成java片段,但是这些java片段怎么没有main方法作为程序的入口啊?
在Tomcat的安装目录下conf目录下的server.xml文件中增加一个xml代码片段,该代码片段中每个属性的含义与用途