• Tomcat启动过程源码分析二


    前言

    上一篇文章分析到,Tomcat通过startup.bat文件启动的时候,传递了一系列参数,最终又调用了Bootstrap.javamain方法,现在我们就来看看Bootstrap.javamain方法都做了什么吧!

    public static void main(String args[]) {
    		//第一部分
            if (daemon == null) {
                // Don't set daemon until init() has completed
                Bootstrap bootstrap = new Bootstrap();
                try {
                    bootstrap.init();
                } catch (Throwable t) {
                    handleThrowable(t);
                    t.printStackTrace();
                    return;
                }
                daemon = bootstrap;
            } else {
                // When running as a service the call to stop will be on a new
                // thread so make sure the correct class loader is used to prevent
                // a range of class not found exceptions.
                Thread.currentThread().setContextClassLoader(daemon.catalinaLoader);
            }
    
    //第二部分
            try {
                String command = "start";
                if (args.length > 0) {
                    command = args[args.length - 1];
                }
    
                if (command.equals("startd")) {
                    args[args.length - 1] = "start";
                    daemon.load(args);
                    daemon.start();
                } else if (command.equals("stopd")) {
                    args[args.length - 1] = "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 if (command.equals("configtest")) {
                    daemon.load(args);
                    if (null==daemon.getServer()) {
                        System.exit(1);
                    }
                    System.exit(0);
                } else {
                    log.warn("Bootstrap: command "" + command + "" does not exist.");
                }
            } catch (Throwable t) {
                // Unwrap the Exception for clearer error reporting
                if (t instanceof InvocationTargetException &&
                        t.getCause() != null) {
                    t = t.getCause();
                }
                handleThrowable(t);
                t.printStackTrace();
                System.exit(1);
            }
    
        }
    

    看源码我们大概看到main方法的代码量很少,大致可以分为两大部分,下面我们就来逐步的分析一下每个部分。

    第一部分

    if (daemon == null) {
                // Don't set daemon until init() has completed
                Bootstrap bootstrap = new Bootstrap();
                try {
                    bootstrap.init();
                } catch (Throwable t) {
                    handleThrowable(t);
                    t.printStackTrace();
                    return;
                }
                daemon = bootstrap;
            } else {
                // When running as a service the call to stop will be on a new
                // thread so make sure the correct class loader is used to prevent
                // a range of class not found exceptions.
                Thread.currentThread().setContextClassLoader(daemon.catalinaLoader);
            }
    
    1. 如果成员变量demon为空,新建Bootstrap对象,调用对象的init方法,然后该对象赋给成员变量demon
    2. 如果demon非空,那么当当前线程的类加载器设置为 demon的加载器,(这个demon.catalinaLoader第一次赋值会在下文提到。)

    第二部分

     try {
                String command = "start";
                if (args.length > 0) {
                    command = args[args.length - 1];
                }
    
                if (command.equals("startd")) {
                    args[args.length - 1] = "start";
                    daemon.load(args);
                    daemon.start();
                } else if (command.equals("stopd")) {
                    args[args.length - 1] = "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 if (command.equals("configtest")) {
                    daemon.load(args);
                    if (null==daemon.getServer()) {
                        System.exit(1);
                    }
                    System.exit(0);
                } else {
                    log.warn("Bootstrap: command "" + command + "" does not exist.");
                }
            } catch (Throwable t) {
                // Unwrap the Exception for clearer error reporting
                if (t instanceof InvocationTargetException &&
                        t.getCause() != null) {
                    t = t.getCause();
                }
                handleThrowable(t);
                t.printStackTrace();
                System.exit(1);
            }
    
    1. 设置command参数为start,如果args存在参数的话,取最后一个(我们这里是启动tomcat所以是start)。
    2. 直接跳转到start的if判断,这里做了三个动作,第一个动作设置deamon的await属性为true,嗲用deamon变量的load方法,调用deamon变量的start方法。

    Bootstrap的main方法总结:

    如果基于启动的话,main方法主要做了4件事情:

    1. new(BootStrap)对象,赋值给成员变量deamon,并且调用了deamon类的init方法。
    2. 设置deamon类的await属性为true
    3. 调用deamon类的load方法。
    4. 调用deamon类的start方法。

    由此可见Tomcat所有的启动过程就几种在init,load,start 三个方法中了,下文我们继续探寻三个方法分别做了什么!

  • 相关阅读:
    出现Unexpected token, expected ","报错原因
    select属性的作用
    程序员无广告版百度
    VUE核心组件
    ajax的作用
    SSH整合
    Unity安装教程
    bean的生命周期
    BeanFactory
    打印机
  • 原文地址:https://www.cnblogs.com/coldridgeValley/p/5515423.html
Copyright © 2020-2023  润新知