百木园-与人分享,
就是让自己快乐。

Tomcat源码分析(二)Bootstrap启动类分析

目录

  • 静态代码块
  • main()方法
  • init()方法
    • initClassLoaders()方法
  • load()方法
  • start()方法

上一章,我们下载源码,并启动了源码,Tomcat源码分析(一)启动Tomcat源码 。
现在,我们来看看Bootstrap启动类做了些什么工作。

静态代码块

设置了catelina.home和catalina.base
点击查看代码
static {
    // Will always be non-null
    // 当前工作目录的路径,总是不会为null
    String userDir = System.getProperty(\"user.dir\");

    // Home first
    String home = System.getProperty(Constants.CATALINA_HOME_PROP);
    File homeFile = null;

    if (home != null) {
        File f = new File(home);
        try {
            homeFile = f.getCanonicalFile();
        } catch (IOException ioe) {
            homeFile = f.getAbsoluteFile();
        }
    }

    if (homeFile == null) {
        // First fall-back. See if current directory is a bin directory
        // in a normal Tomcat install
        File bootstrapJar = new File(userDir, \"bootstrap.jar\");

        if (bootstrapJar.exists()) {
            File f = new File(userDir, \"..\");
            try {
                homeFile = f.getCanonicalFile();
            } catch (IOException ioe) {
                homeFile = f.getAbsoluteFile();
            }
        }
    }

    if (homeFile == null) {
        // Second fall-back. Use current directory
        File f = new File(userDir);
        try {
            homeFile = f.getCanonicalFile();
        } catch (IOException ioe) {
            homeFile = f.getAbsoluteFile();
        }
    }

    catalinaHomeFile = homeFile;
    // 设置了catelina.home
    System.setProperty(Constants.CATALINA_HOME_PROP, catalinaHomeFile.getPath());

    // Then base
    String base = System.getProperty(Constants.CATALINA_BASE_PROP);
    if (base == null) {
        catalinaBaseFile = catalinaHomeFile;
    } else {
        File baseFile = new File(base);
        try {
            baseFile = baseFile.getCanonicalFile();
        } catch (IOException ioe) {
            baseFile = baseFile.getAbsoluteFile();
        }
        catalinaBaseFile = baseFile;
    }
    // 设置了catalina.base
    System.setProperty(Constants.CATALINA_BASE_PROP, catalinaBaseFile.getPath());
}

main()方法

1.加锁新建一个Bootstrap对象,调用init初始化并且赋值给了私有静态对象daemon
2.调用了daemon对象load和start方法,而load和start方法里面利用了反射调用了catalinaDeamon的load和start方法
点击查看代码
/**
 * Main method and entry point when starting Tomcat via the provided
 * scripts.
 *
 * @param args Command line arguments to be processed
 */
public static void main(String args[]) {

    synchronized (daemonLock) {
        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();
            if (null == daemon.getServer()) {
                System.exit(1);
            }
        } 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);
    }
}

init()方法

1.使用initClassLoaders()创建了commonLoader、catalinaLoader和sharedLoader
2.利用反射新建一个org.apache.catalina.startup.Catalina类对象,赋值给了catalinaDeamon。
点击查看代码
/**
 * Initialize daemon.
 * @throws Exception Fatal initialization error
 */
public void init() throws Exception {

    initClassLoaders();

    Thread.currentThread().setContextClassLoader(catalinaLoader);

    SecurityClassLoad.securityClassLoad(catalinaLoader);
    
    
    // Load our startup class and call its process() method
    // 加载启动类并调用其process()方法 
    if (log.isDebugEnabled()) {
        log.debug(\"Loading startup class\");
    }
    Class<?> startupClass = catalinaLoader.loadClass(\"org.apache.catalina.startup.Catalina\");
    Object startupInstance = startupClass.getConstructor().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;
}

initClassLoaders()方法

创建了commonLoader、catalinaLoader和sharedLoader
点击查看代码
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) {
        handleThrowable(t);
        log.error(\"Class loader creation threw exception\", t);
        System.exit(1);
    }
}

load()方法

通过反射调用catalinaDaemon的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()方法

 通过反射调用catalinaDaemon的start()方法
点击查看代码
 /**
 * Start the Catalina daemon.
 * @throws Exception Fatal start error
 */
public void start() throws Exception {
    if (catalinaDaemon == null) {
        init();
    }

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

来源:https://www.cnblogs.com/abing-orz/p/15414558.html
本站部分图文来源于网络,如有侵权请联系删除。

未经允许不得转载:百木园 » Tomcat源码分析(二)Bootstrap启动类分析

相关推荐

  • 暂无文章