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");

    }