Tomat源码---载入相应的资源及解析四(1)
一,进行了以上的类包加载后,现在主要的工作是载入server.xml,并对里面的配置进行解析,最特别的就是里面各个容器的初始化(Server,Service,Engine,Host,Context).
--------------------------------------------------------------------------------------------------------------
Process command line argument (start, startd, stop, stopd)
Class: org.apache.catalina.startup.Bootstrap (assume command->start)
What it does:
a) Catalina.setAwait(true);
b) Catalina.load()
b1) initDirs() -> set properties like
catalina.home
catalina.base == catalina.home (most cases)
b2) initNaming
setProperty(javax.naming.Context.INITIAL_CONTEXT_FACTORY,
org.apache.naming.java.javaURLContextFactory ->default)
b3) createStartDigester()
Configures a digester for the main server.xml elements like
org.apache.catalina.core.StandardServer (can change of course :)
org.apache.catalina.deploy.NamingResources
Stores naming resources in the J2EE JNDI tree
org.apache.catalina.LifecycleListener
implements events for start/stop of major components
org.apache.catalina.core.StandardService
The single entry for a set of connectors,
so that a container can listen to multiple connectors
ie, single entry
org.apache.coyote.tomcat5.CoyoteConnector
Connectors to listen for incoming requests only
It also adds the following rulesets to the digester
NamingRuleSet
EngineRuleSet
HostRuleSet
ContextRuleSet
b4) Load the server.xml and parse it using the digester
Parsing the server.xml using the digester is an automatic
XML-object mapping tool, that will create the objects defined in server.xml
Startup of the actual container has not started yet.
b5) Assigns System.out and System.err to the SystemLogHandler class
b6) Calls intialize on all components, this makes each object register itself with the
JMX agent.
During the process call the Connectors also initialize the adapters.
The adapters are the components that do the request pre-processing.
Typical adapters are HTTP1.1 (default if no protocol is specified,
org.apache.coyote.http11.Http11Protocol)
AJP1.3 for mod_jk etc.
-------------------------------------------------------------------------------------------------------------
运行到了Bootstrap#main()
else if (command.equals("start")) { daemon.setAwait(true); daemon.load(args); daemon.start(); }
接下去主要讲解tomcat的load()方法
Bootstrap#load(args)
private void load(String[] arguments) throws Exception { // Call the load() method String methodName = "load"; Object param[]; Class paramTypes[]; if (arguments==null || arguments.length==0) { paramTypes = null; param = null; } else { paramTypes = new Class[1]; paramTypes[0] = arguments.getClass(); param = new Object[1]; param[0] = arguments; } //通过反射机制运行Catalina#load()方法 Method method = catalinaDaemon.getClass().getMethod(methodName, paramTypes); if (log.isDebugEnabled()) log.debug("Calling startup class " + method); method.invoke(catalinaDaemon, param); }
接着,查看org.apache.catalina.startup.Catalina#load()
// Start a new server instance.
public void load() { long t1 = System.nanoTime(); //初始化路径 initDirs(); // Before digester - it may be needed initNaming(); // Create and execute our Digester //创建该对象,主要是对conf/server.xml进行解析 Digester digester = createStartDigester(); InputSource inputSource = null; InputStream inputStream = null; File file = null; try { file = configFile();//server.xml文件 inputStream = new FileInputStream(file); inputSource = new InputSource("file://" + file.getAbsolutePath()); } catch (Exception e) { ; } if (inputStream == null) { try { inputStream = getClass().getClassLoader() .getResourceAsStream(getConfigFile()); inputSource = new InputSource (getClass().getClassLoader() .getResource(getConfigFile()).toString()); } catch (Exception e) { ; } } // This should be included in catalina.jar // Alternative: don't bother with xml, just create it manually. if( inputStream==null ) { try { inputStream = getClass().getClassLoader() .getResourceAsStream("server-embed.xml"); inputSource = new InputSource (getClass().getClassLoader() .getResource("server-embed.xml").toString()); } catch (Exception e) { ; } } if ((inputStream == null) && (file != null)) { log.warn("Can't load server.xml from " + file.getAbsolutePath()); return; } try { inputSource.setByteStream(inputStream); //把Catalina这个类压入栈顶部 digester.push(this); //压入顶部之后,在digester中就可以此类与server.xml进行相应的解析,比如该类的server实例化 digester.parse(inputSource); inputStream.close(); } catch (Exception e) { log.warn("Catalina.start using " + getConfigFile() + ": " , e); return; } // Stream redirection initStreams(); // Start the new server if (server instanceof Lifecycle) { try { //StandarServer开始进行实例化 server.initialize(); } catch (LifecycleException e) { log.error("Catalina.start", e); } } long t2 = System.nanoTime(); if(log.isInfoEnabled()) log.info("Initialization processed in " + ((t2 - t1) / 1000000) + " ms"); }