Tomcat startup (3) Brief analysis of Catalina

The previous article analyzed Bootstrap to

daemon.setAwait(true);
daemon.load(args);
daemon.start();

These three methods are actually reflection calls to the org.apache.catalina.startup.Catalina class.

There is an explanation of the Catalina class

This Google Translate is really powerful

Startup/Shutdown shell program for Catalina. The following command line options
 are recognized:
?-config {pathname} - Set the pathname of the configuration file to be processed.
 If a relative path is specified, it will be interpreted as relative to the directory
pathname specified by the "catalina.base" system property. [conf/server.xml]
?-help - Display usage information.
?-nonaming - Disable naming support.
?configtest - Try to test the config
?start - Start an instance of Catalina.
?stop - Stop the currently running instance of Catalina.<br>Catalina startup/shutdown shell program. The following command line options are recognized:<br>?-config {pathname} - Set the pathname of the configuration file to be processed. If a relative path is specified,<br>  It will be interpreted relative to the directory pathname specified by the "catalina.base" system property.<br>  [conf/server.xml]<br>?-help - Display usage information.<br>?-nonaming - disable naming support.<br>?configtest - attempt to test the configuration<br>?start - Start an instance of Catalina.<br>?stop - Stop the currently running Catalina instance. 

setAwait load(),start() method

setAwait() is skipped. . . I don’t know why this method sets an await with a boolean value.

In load() method

Several important classes and methods will be explained in detail later

createStartDigester()

Digester.java

InputSource

/**
     * Start a new server instance.
     */
    public void load() {

        long t1 = System.nanoTime();

        initDirs(); This is mainly to obtain the java.io.tmpdir operating system cache temporary directory

        // Before digester - it may be needed
        initNaming(); Initialize the basic configuration of the naming service

        // Create and execute our Digester will explore the function of this method in detail below.
        Digester digester = createStartDigester(); The Digester class is mainly used to process xml configuration files (such as conf/server.xml) and convert it into corresponding java objects according to the xml structure.

        InputSource inputSource = null;
        InputStream inputStream = null;
        File file = null;
        try {
            try {// Configuration file, specified by the command line parameter -config, otherwise the default value conf/server.xml
                file = configFile();
                inputStream = new FileInputStream(file);
                inputSource = new InputSource(file.toURI().toURL().toString());
            } catch (Exception e) {
                if (log.isDebugEnabled()) {
                    log.debug(sm.getString("catalina.configFail", file), e);
                }
            }
            . Omit a lot of preconditions in the middle. It is the operation of judging whether inputStream and inputSource are empty.<br>.<br>.<br>try {
                inputSource.setByteStream(inputStream);
                digester.push(this);<br>//Parse the Server in server.xml and copy it to the server attribute of the Catalina class. Server has only one standard implementation, StandardServer, so the subsequent getServer() returns StandardServer.
                digester.parse(inputSource);
            } catch (SAXParseException spe) {
                log.warn("Catalina.start using " + getConfigFile() + ": " +
                        spe.getMessage());
                return;
            } catch (Exception e) {
                log.warn("Catalina.start using " + getConfigFile() + ": " , e);
                return;
            }
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    //Ignore
                }
            }
        }
//Represents a servlet container A <code>Server</code> element represents the entire Catalina servlet container
        getServer().setCatalina(this); Set an external Catalina component component for the server. Here, set the current Catalina object as an external component.
        getServer().setCatalinaHome(Bootstrap.getCatalinaHomeFile());
        getServer().setCatalinaBase(Bootstrap.getCatalinaBaseFile());

        // Stream redirection redirection of the stream, packaging out and err
        initStreams();//Replace System.out and System.err with a custom PrintStream

        // Start the new server
        try {<!-- --><br>//Prepare the component for starting.<br>//This method should perform any initialization required post object creation.<br>//The following <code>LifecycleEvent</code>s will be fired in the following order:
            getServer().init();
        } catch (LifecycleException e) {
            if (Boolean.getBoolean("org.apache.catalina.startup.EXIT_ON_INIT_FAILURE")) {
                throw new java.lang.Error(e);
            } else {
                log.error("Catalina.start", e);
            }
        }

        long t2 = System.nanoTime();
        if(log.isInfoEnabled()) {
            log.info("Initialization processed in " + ((t2 - t1) / 1000000) + " ms");
        }
    }

Catalina’s start() method

Determine whether the server is empty. If it is empty, call load() to load the component. If it is not empty, call the server.start() method.

This method finally executes the server’s start

Register shutdown hook will be registered after startup. Register shutdown hook

/**Prepare for the beginning of active use of the public methods other than property getters/setters<br>and life cycle methods of this component.
This method should be called before any of the public methods other than property getters/setters<br>and life cycle methods of this component are utilized.
 The following LifecycleEvents will be fired in the following order:
1.BEFORE_START_EVENT: At the beginning of the method. It is as this point the state transitions to LifecycleState.STARTING_PREP.
2.START_EVENT: During the method once it is safe to call start() for any child components.
It is at this point that the state transitions to LifecycleState.
STARTING and that the public methods other than property getters/setters and life cycle methods may be used.
3.AFTER_START_EVENT: At the end of the method, immediately before it returns. It is at this point that the state<br> transitions to LifecycleState.STARTED.
Throws:LifecycleException - if this component detects a fatal error that prevents this component from being used
*/
Get ready to start this active,
This start method is a public method for all components
All server components in tomcat implement the org.apache.catalina.Lifecycle interface.
Explanation of Lifecycle interface Common interface for component life cycle methods Common interface for managing component life cycle
The start method is defined in the Lifecycle interface


getServer().start();

//Register shutdown hook
        if (useShutdownHook) {
            if (shutdownHook == null) {
                shutdownHook = new CatalinaShutdownHook();
            }
            Runtime.getRuntime().addShutdownHook(shutdownHook);

            // If JULI is being used, disable JULI's shutdown hook since
            // shutdown hooks run in parallel and log messages may be lost
            // if JULI's hook completes before the CatalinaShutdownHook()
            LogManager logManager = LogManager.getLogManager();
            if (logManager instanceof ClassLoaderLogManager) {
                ((ClassLoaderLogManager) logManager).setUseShutdownHook(
                        false);
            }
        }<br>

Go to explore in detail. Come out with the divider O(>人<)O

Too long. Next chapter

God-level blog:

Directory about tomcat parsing by holly2k master http://blog.csdn.net/holly2k/article/category/1348477

tomcat source code analysis-Bootstrap operation Catalina