betway必威手机版 > betway必威手机版登录 > Tomcat的服务启动做了些什么,Tomcat7启动分析

原标题:Tomcat的服务启动做了些什么,Tomcat7启动分析

浏览次数:199 时间:2019-06-22

事先分析了汤姆cat的启航脚本,假使从startup.bat先导起步汤姆cat的话会发掘最终会调用org.Apache.catalina.startup.Bootstrap里的main方法,并且传过来的末尾二个命令行参数是start,接下去的起步代码深入分析就从那边开端。

前言

  熟知汤姆cat的技术员们,肯定都领会汤姆cat是何许运维与停止的。对于startup.sh、startup.bat、shutdown.sh、shutdown.bat等剧本可能批处理命令,大家自然理解改什么使用它,不过它们到底是哪些兑现的,极度是shutdown.sh脚本(只怕shutdown.bat)毕竟是什么样和Tomcat进度通讯的呢?本文将经过对汤姆cat7.0的源码阅读,深远剖判这一经过。

  由于在生育条件中,汤姆cat一般安排在Linux系统下,所以本文将以startup.sh和shutdown.sh等shell脚本为准,对汤姆cat的起步与甘休开始展览辨析。

汤姆cat服务运维官方的流水生产线文书档案在源码的webapps/docs/architecture/startup目录下。

 

起步进程剖判

  大家运行汤姆cat的指令如下:

sh startup.sh

就此,将从shell脚本startup.sh开首剖判汤姆cat的开发银行进程。startup.sh的台本代码见代码清单1。

代码清单1

os400=false
case "`uname`" in
OS400*) os400=true;;
esac

# resolve links - $0 may be a softlink
PRG="$0"

while [ -h "$PRG" ] ; do
  ls=`ls -ld "$PRG"`
  link=`expr "$ls" : '.*-> (.*)$'`
  if expr "$link" : '/.*' > /dev/null; then
    PRG="$link"
  else
    PRG=`dirname "$PRG"`/"$link"
  fi
done

PRGDIR=`dirname "$PRG"`
EXECUTABLE=catalina.sh

# Check that target executable exists
if $os400; then
  # -x will Only work on the os400 if the files are:
  # 1. owned by the user
  # 2. owned by the PRIMARY group of the user
  # this will not work if the user belongs in secondary groups
  eval
else
  if [ ! -x "$PRGDIR"/"$EXECUTABLE" ]; then
    echo "Cannot find $PRGDIR/$EXECUTABLE"
    echo "The file is absent or does not have execute permission"
    echo "This file is needed to run this program"
    exit 1
  fi
fi

exec "$PRGDIR"/"$EXECUTABLE" start "$@"

代码清单第11中学有多少个重要的变量,分别是:

  • P奥迪Q3GDI途观:当前shell脚本所在的门路;
  • EXECUTABLE:脚本catalina.sh。

传闻最后一行代码:exec "$PENVISIONGDIMurano"/"$EXECUTABLE" start "$@",大家领略实行了shell脚本catalina.sh,并且传递参数start。catalina.sh中收到到start参数后的实行的脚本分支见代码清单2。

代码清单2

elif [ "$1" = "start" ] ; then

# 此处省略参数校验的脚本

  shift
  touch "$CATALINA_OUT"
  if [ "$1" = "-security" ] ; then
    if [ $have_tty -eq 1 ]; then
      echo "Using Security Manager"
    fi
    shift
    eval ""$_RUNJAVA"" ""$LOGGING_CONFIG"" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS 
      -Djava.endorsed.dirs=""$JAVA_ENDORSED_DIRS"" -classpath ""$CLASSPATH"" 
      -Djava.security.manager 
      -Djava.security.policy==""$CATALINA_BASE/conf/catalina.policy"" 
      -Dcatalina.base=""$CATALINA_BASE"" 
      -Dcatalina.home=""$CATALINA_HOME"" 
      -Djava.io.tmpdir=""$CATALINA_TMPDIR"" 
      org.apache.catalina.startup.Bootstrap "$@" start 
      >> "$CATALINA_OUT" 2>&1 "&"

  else
    eval ""$_RUNJAVA"" ""$LOGGING_CONFIG"" $LOGGING_MANAGER $JAVA_OPTS $CATALINA_OPTS 
      -Djava.endorsed.dirs=""$JAVA_ENDORSED_DIRS"" -classpath ""$CLASSPATH"" 
      -Dcatalina.base=""$CATALINA_BASE"" 
      -Dcatalina.home=""$CATALINA_HOME"" 
      -Djava.io.tmpdir=""$CATALINA_TMPDIR"" 
      org.apache.catalina.startup.Bootstrap "$@" start 
      >> "$CATALINA_OUT" 2>&1 "&"

  fi

  if [ ! -z "$CATALINA_PID" ]; then
    echo $! > "$CATALINA_PID"
  fi

  echo "Tomcat started."

从代码清单2能够看来,最终利用java命令施行了org.apache.catalina.startup.Bootstrap类中的main方法,参数也是start。Bootstrap的main方法的贯彻见代码清单3。

代码清单3

    /**
     * Main method, used for testing only.
     *
     * @param args Command line arguments to be processed
     */
    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) {
                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 {
                log.warn("Bootstrap: command ""   command   "" does not exist.");
            }
        } catch (Throwable t) {
            t.printStackTrace();
        }

    }

从代码清单3方可看来,当传递参数start的时候,command等于start,此时main方法的实施步骤如下:

步骤一 初始化Bootstrap

  Bootstrap的init方法(见代码清单4)的执行步骤如下:

  1. 安装Catalina路线,默以为汤姆cat的根目录;
  2. 早先化汤姆cat的类加载器,并安装线程上下文类加载器(具体完成细节,读者可以参照《TOMCAT源码剖析——类加载种类》一文);
  3. 用反射实例化org.apache.catalina.startup.Catalina对象,并且应用反射调用其setParentClassLoader方法,给Catalina对象设置汤姆cat类加载类别的世界级加载器(Java自带的三类别加载器除此之外)。

代码清单4

 

    /**
     * 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;

    }

 

 

 

步骤二 加载、深入分析server.xml配置文件

  当传递参数start的时候,会调用Bootstrap的load方法(见代码清单5),其作用是用反射调用catalinaDaemon(类型是Catalina)的load方法加载和平消除析server.xml配置文件,具体细节已在《TOMCAT源码剖判——SE中华VVEENCORE.XML文件的加载与解析》一文中详尽介绍,风乐趣的爱侣能够选择阅读。

 

代码清单5

 

    /**
     * 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);

    }

 

 

 

步骤三 启动Tomcat

   当传递参数start的时候,调用Bootstrap的load方法之后会随之调用start方法(见代码清单6)运维汤姆cat,此形式其实是用反射调用了catalinaDaemon(类型是Catalina)的start方法。

代码清单6

    /**
     * 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);

    }

Catalina的start方法(见代码清单7)的推行步骤如下:

  1. 验证Server容器是不是曾经实例化。尽管未有实例化Server容器,还可能会重新调用Catalina的load方法加载和平解决析server.xml,那也表明汤姆cat只同意Server容器通过配备在server.xml的措施变通,用户也得以友善实现Server接口创造自定义的Server容器以代表默许的StandardServer。
  2. 开发银行Server容器,有关容器的运转进程的剖判能够参照《TOMCAT源码深入分析——生命周期管理》一文的源委。
  3. 设置关闭钩子。这么说也许有一点点糟糕精通,那就换个说法。汤姆cat自身也许鉴于外省机器断点,程序bug乃至内部存款和储蓄器溢出导致进程退出,不过汤姆cat大概必要在剥离的时候做一些清监护人业,比如:内部存款和储蓄器清理、对象销毁等。那一个清理动作必要封装在叁个Thread的贯彻中,然后将此Thread对象作为参数字传送递给Runtime的addShutdownHook方法就能够。
  4. 最后调用Catalina的await方法循环等待接受汤姆cat的shutdown命令。
  5. 假诺汤姆cat运行平常化且并未有接受shutdown命令,是不会向下进行stop方法的,当收到到shutdown命令,Catalina的await方法会退出循环等待,然后所有人家试行stop方法甘休汤姆cat。

代码清单7

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

        if (getServer() == null) {
            load();
        }

        if (getServer() == null) {
            log.fatal("Cannot start server. Server instance is not configured.");
            return;
        }

        long t1 = System.nanoTime();

        // Start the new server
        try {
            getServer().start();
        } catch (LifecycleException e) {
            log.error("Catalina.start: ", e);
        }

        long t2 = System.nanoTime();
        if(log.isInfoEnabled())
            log.info("Server startup in "   ((t2 - t1) / 1000000)   " ms");

        try {
            // 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);
                }
            }
        } catch (Throwable t) {
            // This will fail on JDK 1.2. Ignoring, as Tomcat can run
            // fine without the shutdown hook.
        }

        if (await) {
            await();
            stop();
        }

    }

Catalina的await方法(见代码清单8)实际只是代办施行了Server容器的await方法。

代码清单8

    /**
     * Await and shutdown.
     */
    public void await() {

        getServer().await();

    }

 以Server的暗中认可落成StandardServer为例,其await方法(见代码清单9)的试行步骤如下:

  1. 创建socket连接的服务端对象ServerSocket;
  2. 巡回等待接受客户端发出的命令,假诺接收到的指令与SHUTDOWN相配(由于应用了equals,所以shutdown命令必须是大写的),那么退出循环等待。

代码清单9

    public void await() {
        // Negative values - don't wait on port - tomcat is embedded or we just don't like ports gja
        if( port == -2 ) {
            // undocumented yet - for embedding apps that are around, alive.
            return;
        }
        if( port==-1 ) {
            while( true ) {
                try {
                    Thread.sleep( 10000 );
                } catch( InterruptedException ex ) {
                }
                if( stopAwait ) return;
            }
        }

        // Set up a server socket to wait on
        ServerSocket serverSocket = null;
        try {
            serverSocket =
                new ServerSocket(port, 1,
                                 InetAddress.getByName(address));
        } catch (IOException e) {
            log.error("StandardServer.await: create["   address
                                 ":"   port
                                 "]: ", e);
            System.exit(1);
        }

        // Loop waiting for a connection and a valid command
        while (true) {

            // Wait for the next connection
            Socket socket = null;
            InputStream stream = null;
            try {
                socket = serverSocket.accept();
                socket.setSoTimeout(10 * 1000);  // Ten seconds
                stream = socket.getInputStream();
            } catch (AccessControlException ace) {
                log.warn("StandardServer.accept security exception: "
                                     ace.getMessage(), ace);
                continue;
            } catch (IOException e) {
                log.error("StandardServer.await: accept: ", e);
                System.exit(1);
            }

            // Read a set of characters from the socket
            StringBuilder command = new StringBuilder();
            int expected = 1024; // Cut off to avoid DoS attack
            while (expected < shutdown.length()) {
                if (random == null)
                    random = new Random();
                expected  = (random.nextInt() % 1024);
            }
            while (expected > 0) {
                int ch = -1;
                try {
                    ch = stream.read();
                } catch (IOException e) {
                    log.warn("StandardServer.await: read: ", e);
                    ch = -1;
                }
                if (ch < 32)  // Control character or EOF terminates loop
                    break;
                command.append((char) ch);
                expected--;
            }

            // Close the socket now that we are done with it
            try {
                socket.close();
            } catch (IOException e) {
                // Ignore
            }

            // Match against our command string
            boolean match = command.toString().equals(shutdown);
            if (match) {
                log.info(sm.getString("standardServer.shutdownViaPort"));
                break;
            } else
                log.warn("StandardServer.await: Invalid command '"  
                                   command.toString()   "' received");

        }

        // Close the server socket and return
        try {
            serverSocket.close();
        } catch (IOException e) {
            // Ignore
        }

    }

 

至此,汤姆cat运转完成。好些个少人恐怕会问,施行sh shutdown.sh脚本时,是怎么着与汤姆cat进程通讯的吧?假若要与Tomcat的ServerSocket通讯,socket客户端怎么样晓得服务端的连年地址与端口呢?下边会日渐表明。

当大家实行startup脚本时,其实正是反省了下情形变量和把值传递给同目录下的catalina脚本,具体五个剧本分别做了什么样看上边两篇博客就好,笔者恐怕不太懂脚本。

先看下那些main方法的代码:

甘休进程深入分析

我们截至汤姆cat的一声令下如下:

sh shutdown.sh

所以,将从shell脚本shutdown.sh起头深入分析Tomcat的终止进程。shutdown.sh的脚本代码见代码清单10。

代码清单10

os400=false
case "`uname`" in
OS400*) os400=true;;
esac

# resolve links - $0 may be a softlink
PRG="$0"

while [ -h "$PRG" ] ; do
  ls=`ls -ld "$PRG"`
  link=`expr "$ls" : '.*-> (.*)$'`
  if expr "$link" : '/.*' > /dev/null; then
    PRG="$link"
  else
    PRG=`dirname "$PRG"`/"$link"
  fi
done

PRGDIR=`dirname "$PRG"`
EXECUTABLE=catalina.sh

# Check that target executable exists
if $os400; then
  # -x will Only work on the os400 if the files are:
  # 1. owned by the user
  # 2. owned by the PRIMARY group of the user
  # this will not work if the user belongs in secondary groups
  eval
else
  if [ ! -x "$PRGDIR"/"$EXECUTABLE" ]; then
    echo "Cannot find $PRGDIR/$EXECUTABLE"
    echo "The file is absent or does not have execute permission"
    echo "This file is needed to run this program"
    exit 1
  fi
fi

exec "$PRGDIR"/"$EXECUTABLE" stop "$@"

代码清单10和代码清单1不胜相像,个中也可以有多个至关心珍视要的变量,分别是:

  • PENVISIONGDI福特Explorer:当前shell脚本所在的不二等秘书籍;
  • EXECUTABLE:脚本catalina.sh。

基于最终一行代码:exec "$P奥迪Q5GDI奥迪Q5"/"$EXECUTABLE" stop "$@",大家掌握实施了shell脚本catalina.sh,并且传递参数stop。catalina.sh中吸取到stop参数后的施行的脚本分支见代码清单11。

代码清单11

elif [ "$1" = "stop" ] ; then

  #省略参数校验脚本

  eval ""$_RUNJAVA"" $LOGGING_MANAGER $JAVA_OPTS 
    -Djava.endorsed.dirs=""$JAVA_ENDORSED_DIRS"" -classpath ""$CLASSPATH"" 
    -Dcatalina.base=""$CATALINA_BASE"" 
    -Dcatalina.home=""$CATALINA_HOME"" 
    -Djava.io.tmpdir=""$CATALINA_TMPDIR"" 
    org.apache.catalina.startup.Bootstrap "$@" stop
 

从代码清单11能够看来,最后利用java命令实施了org.apache.catalina.startup.Bootstrap类中的main方法,参数是stop。从代码清单3足以见见,当传递参数stop的时候,command等于stop,此时main方法的实行步骤如下:

步骤一 初始化Bootstrap

  早已在起步进程解析中牵线, 不再赘言。

手续二 停止服务

  通过调用Bootstrap的stopServer方法(见代码清单12)结束汤姆cat,其实质是用反射调用catalinaDaemon(类型是Catalina)的stopServer方法。

代码清单12

 

   /**
     * Stop the standalone 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);

    }

 

Catalina的stopServer方法(见代码清单13)的奉行步骤如下:

  1. 创造Digester剖析server.xml文件(此处只剖判<Server>标签),以组织出Server容器(此时Server容器的子容器未有被实例化);
  2. 从实例化的Server容器获取Server的socket监听端口和地方,然后创造Socket对象连接运维汤姆cat时创建的ServerSocket,最终向ServerSocket发送SHUTDOWN命令。依照代码清单9的源委,ServerSocket循环等待接受到SHUTDOWN命令后,最后调用stop方法结束汤姆cat。

代码清单13

    public void stopServer() {
        stopServer(null);
    }

    public void stopServer(String[] arguments) {

        if (arguments != null) {
            arguments(arguments);
        }

        if( getServer() == null ) {
            // Create and execute our Digester
            Digester digester = createStopDigester();
            digester.setClassLoader(Thread.currentThread().getContextClassLoader());
            File file = configFile();
            try {
                InputSource is =
                    new InputSource("file://"   file.getAbsolutePath());
                FileInputStream fis = new FileInputStream(file);
                is.setByteStream(fis);
                digester.push(this);
                digester.parse(is);
                fis.close();
            } catch (Exception e) {
                log.error("Catalina.stop: ", e);
                System.exit(1);
            }
        }

        // Stop the existing server
        try {
            if (getServer().getPort()>0) { 
                Socket socket = new Socket(getServer().getAddress(),
                        getServer().getPort());
                OutputStream stream = socket.getOutputStream();
                String shutdown = getServer().getShutdown();
                for (int i = 0; i < shutdown.length(); i  )
                    stream.write(shutdown.charAt(i));
                stream.flush();
                stream.close();
                socket.close();
            } else {
                log.error(sm.getString("catalina.stopServer"));
                System.exit(1);
            }
        } catch (IOException e) {
            log.error("Catalina.stop: ", e);
            System.exit(1);
        }

    }

最终,大家看看Catalina的stop方法(见代码清单14)的完结,其实行步骤如下:

  1. 将开发银行进程中丰裕的关门钩子移除。汤姆cat运行进程艰巨非凡增多的闭馆钩子为啥又要去掉啊?因为关闭钩子是为着在JVM至极退出后,实行财富的回收专门的学业。主动停止汤姆cat时调用的stop方法里早就包括了财富回收的开始和结果,所以不再需求以此钩子了。
  2. 停下Server容器。有关容器的告一段落内容,请阅读《TOMCAT源码解析——生命周期管理》一文。

代码清单14

    /**
     * Stop an existing server instance.
     */
    public void stop() {

        try {
            // Remove the ShutdownHook first so that server.stop() 
            // doesn't get invoked twice
            if (useShutdownHook) {
                Runtime.getRuntime().removeShutdownHook(shutdownHook);

                // If JULI is being used, re-enable JULI's shutdown to ensure
                // log messages are not lost jiaan
                LogManager logManager = LogManager.getLogManager();
                if (logManager instanceof ClassLoaderLogManager) {
                    ((ClassLoaderLogManager) logManager).setUseShutdownHook(
                            true);
                }
            }
        } catch (Throwable t) {
            // This will fail on JDK 1.2. Ignoring, as Tomcat can run
            // fine without the shutdown hook.
        }

        // Shut down the server
        try {
            getServer().stop();
        } catch (LifecycleException e) {
            log.error("Catalina.stop", e);
        }

    }

startup http://www.cnblogs.com/fantiantian/p/3620022.html

 1 /**   2      * Main method and entry point when starting Tomcat via the provided   3      * scripts.   4      *   5      * @param args Command line arguments to be processed   6      */   7     public static void main(String args[]) {   8    9         if (daemon == null) {  10             // Don't set daemon until init() has completed  11             Bootstrap bootstrap = new Bootstrap();  12             try {  13                 bootstrap.init();  14             } catch (Throwable t) {  15                 handleThrowable(t);  16                 t.printStackTrace();  17                 return;  18             }  19             daemon = bootstrap;  20         } else {  21             // When running as a service the call to stop will be on a new  22             // thread so make sure the correct class loader is used to prevent  23             // a range of class not found exceptions.  24             Thread.currentThread().setContextClassLoader(daemon.catalinaLoader);  25         }  26   27         try {  28             String command = "start";  29             if (args.length > 0) {  30                 command = args[args.length - 1];  31             }  32   33             if (command.equals("startd")) {  34                 args[args.length - 1] = "start";  35                 daemon.load(args);  36                 daemon.start();  37             } else if (command.equals("stopd")) {  38                 args[args.length - 1] = "stop";  39                 daemon.stop();  40             } else if (command.equals("start")) {  41                 daemon.setAwait(true);  42                 daemon.load(args);  43                 daemon.start();  44             } else if (command.equals("stop")) {  45                 daemon.stopServer(args);  46             } else if (command.equals("configtest")) {  47                 daemon.load(args);  48                 if (null==daemon.getServer()) {  49                     System.exit(1);  50                 }  51                 System.exit(0);  52             } else {  53                 log.warn("Bootstrap: command ""   command   "" does not exist.");  54             }  55         } catch (Throwable t) {  56             // Unwrap the Exception for clearer error reporting  57             if (t instanceof InvocationTargetException &&  58                     t.getCause() != null) {  59                 t = t.getCause();  60             }  61             handleThrowable(t);  62             t.printStackTrace();  63             System.exit(1);  64         }  65   66     }

总结

  通过对Tomcat源码的剖析我们询问到汤姆cat的开发银行和终止都离不开org.apache.catalina.startup.Bootstrap。当结束汤姆cat时,已经运营的汤姆cat作为socket服务端,停止脚本运行的Bootstrap进度作为socket客户端向服务端发送shutdown命令,三个经过经过共享server.xml里Server标签的端口以及地点音讯发掘了socket的通讯。

 

如需转发,请评释本文作者及出处——小编:jiaan.gja,本文原创首发:微博,原版的书文链接:

 

 

catalina http://www.cnblogs.com/fantiantian/p/3623740.html

此地的daemon是Bootstrap类中的二个静态成员变量,类型正是Bootstrap,第10行的笺注已经注明在调用过init方法之后才会给该变量赋值,早先时将是null,所以率先将实例化三个Bootstrap对象,接着调用init方法,该措施代码如下:

而catalina最要害的正是实践了Tomcat的启航辅导类Bootstarp的main方法。具体大家看main方法主要做了怎么。

 1 /**   2      * Initialize daemon.   3      */   4     public void init()   5         throws Exception   6     {   7    8         // Set Catalina path   9         setCatalinaHome();  10         setCatalinaBase();  11   12         initClassLoaders();  13   14         Thread.currentThread().setContextClassLoader(catalinaLoader);  15   16         SecurityClassLoad.securityClassLoad(catalinaLoader);  17   18         // Load our startup class and call its process() method  19         if (log.isDebugEnabled())  20             log.debug("Loading startup class");  21         Class<?> startupClass =  22             catalinaLoader.loadClass  23             ("org.apache.catalina.startup.Catalina");  24         Object startupInstance = startupClass.newInstance();  25   26         // Set the shared extensions class loader  27         if (log.isDebugEnabled())  28             log.debug("Setting startup class properties");  29         String methodName = "setParentClassLoader";  30         Class<?> paramTypes[] = new Class[1];  31         paramTypes[0] = Class.forName("java.lang.ClassLoader");  32         Object paramValues[] = new Object[1];  33         paramValues[0] = sharedLoader;  34         Method method =  35             startupInstance.getClass().getMethod(methodName, paramTypes);  36         method.invoke(startupInstance, paramValues);  37   38         catalinaDaemon = startupInstance;  39   40     }

从文书档案中的图来看,Bootstrap首要做了四件事。

本文由betway必威手机版发布于betway必威手机版登录,转载请注明出处:Tomcat的服务启动做了些什么,Tomcat7启动分析

关键词: Java Java核心 Tomcat原理 Tomcat soc

上一篇:PHP环境搭建,php环境教程

下一篇:没有了