`
bushuang1983
  • 浏览: 4407 次
  • 性别: Icon_minigender_1
  • 来自: 冥王星
社区版块
存档分类
最新评论
阅读更多

1.首先下载tomcat7源码,下载地址http://tomcat.apache.org/download-70.cgi

 

2.Bootstrap类是容器启动和停止的执行类。

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


package org.apache.catalina.startup;


import java.io.File;
import java.lang.management.ManagementFactory;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.StringTokenizer;

import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.ObjectName;

import org.apache.catalina.Globals;
import org.apache.catalina.security.SecurityClassLoad;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;


/**
 * Bootstrap loader for Catalina.  This application constructs a class loader
 * for use in loading the Catalina internal classes (by accumulating all of the
 * JAR files found in the "server" directory under "catalina.home"), and
 * starts the regular execution of the container.  The purpose of this
 * roundabout approach is to keep the Catalina internal classes (and any
 * other classes they depend on, such as an XML parser) out of the system
 * class path and therefore not visible to application level classes.
 *
 * @author Craig R. McClanahan
 * @author Remy Maucherat
 * @version $Id: Bootstrap.java 1031043 2010-11-04 15:47:56Z funkman $
 */

public final class Bootstrap {

    private static final Log log = LogFactory.getLog(Bootstrap.class);

    // -------------------------------------------------------------- Constants


    protected static final String CATALINA_HOME_TOKEN = "${" + Globals.CATALINA_HOME_PROP + "}";
    protected static final String CATALINA_BASE_TOKEN = "${" + Globals.CATALINA_BASE_PROP + "}";


    // ------------------------------------------------------- Static Variables


    /**
     * Daemon object used by main.
     */
    private static Bootstrap daemon = null;


    // -------------------------------------------------------------- Variables


    /**
     * Daemon reference.
     */
    private Object catalinaDaemon = null;


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


    // -------------------------------------------------------- Private Methods

//   初始化common,server,shared这三个类加载器,common类加载器是server和shared加载器的父加载器,类加载器就像一个沙箱一样隔离加载器类.
    private void initClassLoaders() {
        try {
//        	common加载器加载的类对tomcat容器和web应用都可见
            commonLoader = createClassLoader("common", null);
            if( commonLoader == null ) {
//          如果没有配置文件或者配置文件值为空,则得到加载当前Bootstrap对象的类加载器.              
                commonLoader=this.getClass().getClassLoader();
            }
//          server加载器加载的类只对tomcat容器可见   
            catalinaLoader = createClassLoader("server", commonLoader);
//          shared加载器加载的类只对web应用可见
            sharedLoader = createClassLoader("shared", commonLoader);
        } catch (Throwable t) {
            handleThrowable(t);
            log.error("Class loader creation threw exception", t);
            System.exit(1);
        }
    }


    private ClassLoader createClassLoader(String name, ClassLoader parent)
        throws Exception {
/**    
 *	    得到conf/catalina.properties属性文件中name.loader的值.详见CatalinaProperties类loadProperties方法
 *   	common类加载器的默认值是:  common.loader=${catalina.base}/lib,${catalina.base}/lib/*.jar,${catalina.home}/lib,${catalina.home}/lib/*.jar
 *    	server类加载器的默认值是:  server.loader=
 *   	share类加载器的默认值是:   shared.loader=
 */
        String value = CatalinaProperties.getProperty(name + ".loader");
        
//      如果值为空则返回父类加载器,默认情况下server类加载器和share类加载器都是空.
        if ((value == null) || (value.equals("")))
            return parent;

//      类加载器所加载的类所在的仓库位置
        ArrayList<String> repositoryLocations = new ArrayList<String>();
        
//      类加载器所加载的类的仓库类型,有4种类型ClassLoaderFactory.IS_URL,ClassLoaderFactory.IS_DIR,ClassLoaderFactory.IS_JAR,ClassLoaderFactory.IS_GLOB        
        ArrayList<Integer> repositoryTypes = new ArrayList<Integer>();
        int i;
        
/**
 *     不同仓库以","号分隔,比如${catalina.base}/lib,${catalina.base}/lib/*.jar,${catalina.home}/lib,${catalina.home}/lib/*.jar
 */       
        StringTokenizer tokenizer = new StringTokenizer(value, ",");
        while (tokenizer.hasMoreElements()) {
//        	得到其中一个仓库
            String repository = tokenizer.nextToken();

// 			判断仓库值是否被替换过,用于记录日志
            boolean replace = false;
//          记录仓库的初始值
            String before = repository;
//          如果仓库值包含${catalina.home}字符,则用真实的值替换掉
            while ((i=repository.indexOf(CATALINA_HOME_TOKEN))>=0) {
                replace=true;
//          i大于0的情况是仓库为ClassLoaderFactory.IS_URL类型的时候,比如http://localhost/${catalina.base}/lib
                if (i>0) {
                repository = repository.substring(0,i) + getCatalinaHome()
                    + repository.substring(i+CATALINA_HOME_TOKEN.length());
                } else {
                    repository = getCatalinaHome()
                        + repository.substring(CATALINA_HOME_TOKEN.length());
                }
            }
//          如果仓库值包含${catalina.base}字符,则用真实的值替换掉
            while ((i=repository.indexOf(CATALINA_BASE_TOKEN))>=0) {
                replace=true;
                if (i>0) {
                repository = repository.substring(0,i) + getCatalinaBase()
                    + repository.substring(i+CATALINA_BASE_TOKEN.length());
                } else {
                    repository = getCatalinaBase()
                        + repository.substring(CATALINA_BASE_TOKEN.length());
                }
            }
            if (replace && log.isDebugEnabled())
                log.debug("Expanded " + before + " to " + repository);

            // Check for a JAR URL repository
            try {
/**
 * 		如果仓库不是ClassLoaderFactory.IS_URL类型的时候就会发生MalformedURLException异常,不会执行try下面的语句,如果是ClassLoaderFactory.IS_URL类型则记录下
 * 		仓库位置和仓库类型并返回解析下一个仓库
 */                   	
                new URL(repository);
                repositoryLocations.add(repository);
                repositoryTypes.add(ClassLoaderFactory.IS_URL);
                continue;
            } catch (MalformedURLException e) {
                // Ignore
            }

            if (repository.endsWith("*.jar")) {
                repository = repository.substring
                    (0, repository.length() - "*.jar".length());
                repositoryLocations.add(repository);
                repositoryTypes.add(ClassLoaderFactory.IS_GLOB);
            } else if (repository.endsWith(".jar")) {
                repositoryLocations.add(repository);
                repositoryTypes.add(ClassLoaderFactory.IS_JAR);
            } else {
                repositoryLocations.add(repository);
                repositoryTypes.add(ClassLoaderFactory.IS_DIR);
            }
        }

        String[] locations = repositoryLocations.toArray(new String[0]);
        Integer[] types = repositoryTypes.toArray(new Integer[0]);
//      根据仓库位置,类型,父类加载器创建类加载器
        ClassLoader classLoader = ClassLoaderFactory.createClassLoader
            (locations, types, parent);

//      得到Mbean服务器.
        MBeanServer mBeanServer = null;
        if (MBeanServerFactory.findMBeanServer(null).size() > 0) {
            mBeanServer = MBeanServerFactory.findMBeanServer(null).get(0);
        } else {
            mBeanServer = ManagementFactory.getPlatformMBeanServer();
        }

// 		在服务器中注册类加载器以便管理
        ObjectName objectName =
            new ObjectName("Catalina:type=ServerClassLoader,name=" + name);
        mBeanServer.registerMBean(classLoader, objectName);

        return classLoader;

    }


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

// 		设置catalina.home
        setCatalinaHome();
        
//      设置catalina.base  
        setCatalinaBase();

//      初始化common,server,share类加载器,并在Mbean服务器中注册
        initClassLoaders();

//      设置当前的类加载器上下文为server类加载器
        Thread.currentThread().setContextClassLoader(catalinaLoader);

//      通过server类加载器加载核心类
        SecurityClassLoad.securityClassLoad(catalinaLoader);

        // Load our startup class and call its process() method
        if (log.isDebugEnabled())
            log.debug("Loading startup class");
//     动态加载org.apache.catalina.startup.Catalina类,并创建一个实例,Catalina是一个守护进程
        Class<?> startupClass =
            catalinaLoader.loadClass
            ("org.apache.catalina.startup.Catalina");
        Object startupInstance = startupClass.newInstance();

        // Set the shared extensions class loader,利用反射调用Catalina类的setParentClassLoader方法
        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);
//      Catalina实例的引用
        catalinaDaemon = startupInstance;

    }


    /**
     * 利用发射调用Catalina的load方法
     */
    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);

    }


    /**
     * getServer() for configtest
     */
    private Object getServer() throws Exception {

        String methodName = "getServer";
        Method method =
            catalinaDaemon.getClass().getMethod(methodName);
        return method.invoke(catalinaDaemon);

    }


    // ----------------------------------------------------------- Main Program


    /**
     * Load the Catalina daemon.
     */
    public void init(String[] arguments)
        throws Exception {

        init();
        load(arguments);

    }


    /**
     * 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 standalone server.
     */
    public void stopServer()
        throws Exception {

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

    }


   /**
     * 利用反射调用Catalina类的stopServer方法
     */
    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);

    }


    /**
     * 利用反射调用Catalina类的setAwait方法
     */
    public void setAwait(boolean await)
        throws Exception {

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

    }

    public boolean getAwait()
        throws Exception
    {
        Class<?> paramTypes[] = new Class[0];
        Object paramValues[] = new Object[0];
        Method method =
            catalinaDaemon.getClass().getMethod("getAwait", paramTypes);
        Boolean b=(Boolean)method.invoke(catalinaDaemon, paramValues);
        return b.booleanValue();
    }


    /**
     * Destroy the Catalina Daemon.
     */
    public void destroy() {

        // FIXME

    }


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

 //     deamon是bootstrap初始化的标识
        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;
        }

        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) {
            handleThrowable(t);
            t.printStackTrace();
            System.exit(1);
        }

    }

    public void setCatalinaHome(String s) {
        System.setProperty(Globals.CATALINA_HOME_PROP, s);
    }

    public void setCatalinaBase(String s) {
        System.setProperty(Globals.CATALINA_BASE_PROP, s);
    }


    /**
     * 如果catalina.base没有设置过,则设置catalina.home为当前工作目录
     */
    private void setCatalinaBase() {

        if (System.getProperty(Globals.CATALINA_BASE_PROP) != null)
            return;
        if (System.getProperty(Globals.CATALINA_HOME_PROP) != null)
            System.setProperty(Globals.CATALINA_BASE_PROP,
                               System.getProperty(Globals.CATALINA_HOME_PROP));
        else
            System.setProperty(Globals.CATALINA_BASE_PROP,
                               System.getProperty("user.dir"));

    }


    /**
     * 如果catalina.home没有设置过,则设置catalina.home为当前工作目录
     */
    private void setCatalinaHome() {
//   
        if (System.getProperty(Globals.CATALINA_HOME_PROP) != null)
            return;

        File bootstrapJar =
            new File(System.getProperty("user.dir"), "bootstrap.jar");
//      如果当前目录下存在bootstrap.jar,则设置catalina.home为当前工作目录的上一级目录
        if (bootstrapJar.exists()) {
            try {
                System.setProperty
                    (Globals.CATALINA_HOME_PROP,
                     (new File(System.getProperty("user.dir"), ".."))
                     .getCanonicalPath());
            } catch (Exception e) {
                // Ignore
                System.setProperty(Globals.CATALINA_HOME_PROP,
                                   System.getProperty("user.dir"));
            }
        } else {
            System.setProperty(Globals.CATALINA_HOME_PROP,
                               System.getProperty("user.dir"));
        }

    }


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


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


    // Copied from ExceptionUtils since that class is not visible during start
    private static void handleThrowable(Throwable t) {
        if (t instanceof ThreadDeath) {
            throw (ThreadDeath) t;
        }
        if (t instanceof VirtualMachineError) {
            throw (VirtualMachineError) t;
        }
        // All other instances of Throwable will be silently swallowed
    }
}
分享到:
评论

相关推荐

    bootstrap bootstrap-3.3.7

    这个里面 包含整个bootstrap源程序 你所需要的都在了、里面.Bootstrap,来自 Twitter,是目前最受欢迎的前端框架。Bootstrap 是基于 HTML、CSS、JAVASCRIPT 的,它简洁灵活,使得 Web 开发更加快捷。 本教程将向您...

    Bootstrap5 图标库 bootstrap-icons

    Bootstrap5图标库bootstrap-icons是前端开发中一个非常实用的资源,它为开发者提供了大量美观、一致的SVG图标,可以方便地集成到Bootstrap5项目中,为网页设计增添丰富的视觉元素。Bootstrap图标库的设计理念是简洁...

    bootstrap文件及bootstrap图标大全

    Bootstrap,由Twitter开发,是一款广泛应用于前端开发的开源框架,以其简洁、直观和强大的特性而闻名。Bootstrap 3.3.7是该框架的一个稳定版本,提供了丰富的组件、响应式设计以及易于定制的样式,旨在帮助开发者...

    Bootstrap后台登录界面模板_后台模板_bootstrap_

    Bootstrap是世界上最流行的前端开发框架之一,它为开发者提供了丰富的组件和设计工具,使得构建响应式、移动优先的网站变得简单高效。在这个“Bootstrap后台登录界面模板”中,我们可以找到一个预设计好的登录页面...

    开发工具 dataTables.bootstrap.min

    开发工具 dataTables.bootstrap.min开发工具 dataTables.bootstrap.min开发工具 dataTables.bootstrap.min开发工具 dataTables.bootstrap.min开发工具 dataTables.bootstrap.min开发工具 dataTables.bootstrap.min...

    bootstrap 3.4.1 中文文档 离线

    bootstrap中文文档,实际上是将bootstrap整个站扒下来了,使用浏览器打开index.htm即可,注意编码格式为UTF-8,如果出现乱码考虑修改浏览器编码。 主要便于离线环境下前端开发使用。 Bootstrap 是最受欢迎的 HTML...

    bootstrap源码.rar

    Bootstrap是世界上最流行的前端开发框架,由Twitter的开发者创建,它为快速构建响应式、移动优先的网站提供了强大的工具。这个“bootstrap源码.rar”压缩包包含的正是Bootstrap框架的源代码,这对于理解其工作原理、...

    Bootstrap 图标库下载

    Bootstrap Icons:Bootstrap 有史以来第一次拥有自己的图标库,并且是专门为 Bootstrap 的组件和文档定制开发的。 Bootstrap Icons 的设计初衷是与 Bootstrap 组件配合使用,从表单到导航组件等。Bootstrap Icons ...

    bootstrap-4.6.2下载bootstrap.min.cssbootstrap.bundle.min.js

    在"bootstrap-4.6.2下载bootstrap.min.cssbootstrap.bundle.min.js"的标题中,我们可以看到两个关键文件:`bootstrap.min.css`和`bootstrap.bundle.min.js`。`bootstrap.min.css`是Bootstrap的核心CSS文件,经过压缩...

    bootstrap.min.js和bootstrap.min.css

    Bootstrap是世界上最受欢迎的前端开发框架之一,用于构建响应式、移动优先的网页项目。这个框架提供了丰富的组件、样式和JavaScript插件,极大地简化了网页设计和开发过程。在标题和描述中提到的"bootstrap.min.js...

    bootstrap布局设计器

    Bootstrap是世界上最流行的前端开发框架之一,它为开发者提供了丰富的组件和设计工具,使得构建响应式、移动优先的网站变得简单高效。"Bootstrap布局设计器"是一个专门用于创建和编辑Bootstrap布局的工具,它可以...

    Bootstrap自动适应PC、平板、手机的Bootstrap栅格系统

    Bootstrap栅格系统是一种基于12列的响应式布局框架,旨在帮助开发者构建适应不同设备屏幕大小的网页。这种系统能够确保网页在PC、平板、手机等不同设备上呈现出优雅的自适应效果,优化用户体验。Bootstrap栅格系统的...

    bootstrap-3.4.1-dist.zip,bootstrap-4.6.1-dist.zip

    Bootstrap是世界上最受欢迎的前端开发框架之一,用于构建响应式布局和移动设备优先的Web项目。这个框架由Twitter的开发者创建,极大地简化了网页设计和开发流程。本压缩包包含两个版本的Bootstrap——3.4.1和4.6.1,...

    bootstrap评论列表模板

    Bootstrap评论列表模板是一种基于Bootstrap前端框架设计的网页组件,它为网站提供了一种标准化的、美观的、响应式的用户评论展示方式。Bootstrap是由Twitter开发并开源的,它是一套强大的前端开发工具集,包含了丰富...

    bootstrap实现的自适应页面简单应用示例

    Bootstrap实现的自适应页面简单应用示例 在本文中,我们将详细介绍Bootstrap实现的自适应页面简单应用示例,结合具体实例形式分析了基于Bootstrap的列表布局结构页面实现与使用技巧。 首先,让我们了解什么是...

    Bootstrap实现登录校验表单(带验证码)

    Bootstrap是一个流行的前端开发框架,用于快速构建响应式和移动优先的网站。在本文中,我们将探讨如何使用Bootstrap来创建一个带有验证码和验证功能的登录表单。 首先,要创建这样一个表单,我们需要引入Bootstrap...

    Bootstrap中文手册-v4.3.1.pdf

    Bootstrap 是一个广泛使用的前端开发框架,用于创建响应式网站和应用程序。它最初由 Twitter 的开发人员马克·奥托(Mark Otto)和雅各布·桑特森(Jacob Thornton)开发,并已成为世界上使用最广泛的开源前端框架之...

    bootstrap 期末项目 设计报告 模板

    Bootstrap 期末项目设计报告模板知识点总结 一、Bootstrap 介绍 Bootstrap 是一个流行的前端框架,用于构建响应式、mobile-first 的 Web 应用程序。它提供了一些常用的 HTML、CSS 和 JavaScript 组件,可以快速...

    bootstrap3.3.5中文手册

    Bootstrap是世界上最受欢迎的前端开发框架,它为创建响应式、移动优先的网站提供了一套强大的工具。Bootstrap3.3.5是该框架的一个稳定版本,它优化了对各种设备的适应性,使得开发者能够轻松地构建一致且美观的界面...

    bootstrap详细学习课件文档

    Bootstrap 详细学习课件文档 Bootstrap 是由美国 Twitter 公司开发的,目前最受欢迎的前端框架。Bootstrap 是基于 HTML、CSS、JAVASCRIPT 的前端框架,简单灵活,可以大大提高 web 开发效率。 Bootstrap 概述 ...

Global site tag (gtag.js) - Google Analytics