tomcat6源码研究:tomcat启动

tomcat的启动类在Bootstrap.java中,main方法如下:

/**
     * Main method, used for testing only.
     *
     * @param args Command line arguments to be processed
     */
    public static void main(String args[]) {


        if (daemon == null) {
            daemon = new Bootstrap();
            try {
                daemon.init();
            } catch (Throwable t) {
                t.printStackTrace();
                return;
            }
        }


        try {
            String command = "start";
            if (args.length > 0) {
                command = args[args.length - 1];
            }


            if (command.equals("startd")) {
                args[0] = "start";
                daemon.load(args);
                daemon.start();
            } else if (command.equals("stopd")) {
                args[0] = "stop";
                daemon.stop();
            } else if (command.equals("start")) {
                daemon.setAwait(true);
                daemon.load(args);
                daemon.start();
            } else if (command.equals("stop")) {
                daemon.stopServer(args);
            } else {
                log.warn("Bootstrap: command \"" + command + "\" does not exist.");
            }
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }

初始化方法:init()

/**
     * Initialize daemon.
     */
    public void init()
        throws Exception
    {


        // Set Catalina path
        setCatalinaHome();
        setCatalinaBase();


        initClassLoaders();


        Thread.currentThread().setContextClassLoader(catalinaLoader);


        SecurityClassLoad.securityClassLoad(catalinaLoader);


        // Load our startup class and call its process() method
        if (log.isDebugEnabled())
            log.debug("Loading startup class");
        Class startupClass =
            catalinaLoader.loadClass
            ("org.apache.catalina.startup.Catalina");
        Object startupInstance = startupClass.newInstance();


        // Set the shared extensions class loader
        if (log.isDebugEnabled())
            log.debug("Setting startup class properties");
        String methodName = "setParentClassLoader";
        Class paramTypes[] = new Class[1];
        paramTypes[0] = Class.forName("java.lang.ClassLoader");
        Object paramValues[] = new Object[1];
        paramValues[0] = sharedLoader;
        Method method =
            startupInstance.getClass().getMethod(methodName, paramTypes);
        method.invoke(startupInstance, paramValues);


        catalinaDaemon = startupInstance;
    }


tomcat启动时初始化三个类加载器,commonLoader允许加载%CATALINA_HOME%/common/classes, %CATALINA_HOME%/common/endorsed, and %CATALINA_HOME%/common/lib这三个目录下的类, 

catalinaLoader负责加载catalina servlet容器运行时需要的类,包括%CATALINA_HOME%/server/classes and %CATALINA_HOME%/server/lib 这两个目录下的类以及所有commonLoader能加载的类,

sharedLoader负责加载 %CATALINA_HOME%/shared/classesand %CATALJNA_HOME%/shared/lib 
目录下的类以及所有commonLoader能加载的类。然后sharedLoader被分配给跟部署在tomcat下context相关的应用程序的父加载器。注意:sharedLoader不能加载Catalina内部的类和定义在CLASSPATH环境变量下的类。

 protected ClassLoader commonLoader = null;
 protected ClassLoader catalinaLoader = null;
 protected ClassLoader sharedLoader = null;

private void initClassLoaders() {
        try {
            commonLoader = createClassLoader("common", null);
            if( commonLoader == null ) {
                // no config file, default to this loader - we might be in a 'single' env.
                commonLoader=this.getClass().getClassLoader();
            }
            catalinaLoader = createClassLoader("server", commonLoader);
            sharedLoader = createClassLoader("shared", commonLoader);
        } catch (Throwable t) {
            log.error("Class loader creation threw exception", t);
            System.exit(1);
        }
    }


load方法

/**
     * Load daemon.
     */
    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;
        }
        Method method = 
            catalinaDaemon.getClass().getMethod(methodName, paramTypes);
        if (log.isDebugEnabled())
            log.debug("Calling startup class " + method);
        method.invoke(catalinaDaemon, param);
    }


start(),stop(),stopServer(),stopServer(String[] arguments),setAwait(boolean await)
    /**
     * Start the Catalina daemon.
     */
    public void start()
        throws Exception {
        if( catalinaDaemon==null ) init();


        Method method = catalinaDaemon.getClass().getMethod("start", (Class [] )null);
        method.invoke(catalinaDaemon, (Object [])null);


    }
    /**
     * Stop the Catalina Daemon.
     */
    public void stop()
        throws Exception {


        Method method = catalinaDaemon.getClass().getMethod("stop", (Class [] ) null);
        method.invoke(catalinaDaemon, (Object [] ) null);


    }

    /**
     * Stop the standlone server.
     */
    public void stopServer()
        throws Exception {


        Method method = 
            catalinaDaemon.getClass().getMethod("stopServer", (Class []) null);
        method.invoke(catalinaDaemon, (Object []) null);


    }
   /**
     * Stop the standlone server.
     */
    public void stopServer(String[] arguments)
        throws Exception {


        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;
        }
        Method method = 
            catalinaDaemon.getClass().getMethod("stopServer", paramTypes);
        method.invoke(catalinaDaemon, param);


    }
    /**
     * Set flag.
     */
    public void setAwait(boolean await)
        throws Exception {


        Class paramTypes[] = new Class[1];
        paramTypes[0] = Boolean.TYPE;
        Object paramValues[] = new Object[1];
        paramValues[0] = new Boolean(await);
        Method method = 
            catalinaDaemon.getClass().getMethod("setAwait", paramTypes);
        method.invoke(catalinaDaemon, paramValues);
    }

getCatalinaBase()和getCatalinaHome() 方法,这两个方法的前面的值为空,则取后面的值

/**
     * Get the value of the catalina.home environment variable.
     */
    public static String getCatalinaHome() {
        return System.getProperty("catalina.home",
                                  System.getProperty("user.dir"));
    }

    /**
     * Get the value of the catalina.base environment variable.
     */
    public static String getCatalinaBase() {
        return System.getProperty("catalina.base", getCatalinaHome());
    }

上一篇:linux登陆阿里云镜像仓库报错:Error response from daemon: Get https


下一篇:修改docker容器存放位置