tomcat 启动和关闭源码查看

private static Bootstrap daemon = null; 如果没有,这初始化

调用BootStrap中的init方法:
1.this.initClassLoaders();
:    if deamon==null
 初始化Bootstrap接着调用Bootstrap的init方法:
   this.initClassLoaders(),初始化三个类加载器commonLoader,
catalinaLoader,sharedLoader。其中commonLoader加载器可以读取
common/classes,common/endorsed,common/lib目录下的Java类,
catalinaLoader负责加载server/lib,/server/classes,sharedLoader
负责加载/shared/classes,/shared/lib。其中commonLoader,是
catalinaLoader,sharedLoader父类加载器。让deamon=t;
  try {
            this.commonLoader = this.createClassLoader("common", (ClassLoader)null);
            if(this.commonLoader == null) {
                this.commonLoader = this.getClass().getClassLoader();
            }

            this.catalinaLoader = this.createClassLoader("server", this.commonLoader);
            this.sharedLoader = this.createClassLoader("shared", this.commonLoader);
        } catch (Throwable var2) {
            handleThrowable(var2);
            log.error("Class loader creation threw exception", var2);
            System.exit(1);
        }
 else
Thread.currentThread().setContextClassLoader(daemon.catalinaLoader);//线程上下文切换器

2.调用catalinaLodader加载器加载org.apache.catalina.startup.Catalina,并完成初始化
获取该类当中的setParentClassLoader方法调用ClassLoader,将sharedLoader放入。
this.catalinaDaemon=this.catalinaLoader.loadClass("org.apache.catalina.startup.Catalina").startupClass.newInstance();
 this.initClassLoaders();
        Thread.currentThread().setContextClassLoader(this.catalinaLoader);
        SecurityClassLoad.securityClassLoad(this.catalinaLoader);
        if(log.isDebugEnabled()) {
            log.debug("Loading startup class");
        }

        Class startupClass = this.catalinaLoader.loadClass("org.apache.catalina.startup.Catalina");
        Object startupInstance = startupClass.newInstance();
        if(log.isDebugEnabled()) {
            log.debug("Setting startup class properties");
        }

        String methodName = "setParentClassLoader";
        Class[] paramTypes = new Class[]{Class.forName("java.lang.ClassLoader")};
        Object[] paramValues = new Object[]{this.sharedLoader};
        Method method = startupInstance.getClass().getMethod(methodName, paramTypes);
        method.invoke(startupInstance, paramValues);
        this.catalinaDaemon = startupInstance;


3.判断启动参数和停止参数
 try {
            String t2 = "start";
            if(args.length > 0) {
                t2 = args[args.length - 1];
            }

            if(t2.equals("startd")) {
                args[args.length - 1] = "start";
                daemon.load(args);
                daemon.start();
            } else if(t2.equals("stopd")) {
                args[args.length - 1] = "stop";
                daemon.stop();
            } else if(t2.equals("start")) {
                daemon.setAwait(true);
                daemon.load(args);
                daemon.start();
            } else if(t2.equals("stop")) {
                daemon.stopServer(args);
            } else if(t2.equals("configtest")) {
                daemon.load(args);
                if(null == daemon.getServer()) {
                    System.exit(1);
                }

                System.exit(0);
            } else {
                log.warn("Bootstrap: command \"" + t2 + "\" does not exist.");
            }

4.
    3 中的load方法
     Method method = this.catalinaDaemon.getClass().getMethod(methodName, paramTypes);  //方法名,调用参数
     调用org.apache.catalina.startup.Catalina中的load方法:
     method.invoke(this.catalinaDaemon, param);
    3.1 创建Digester 类
      使用digester映射JavaBean和xml
    3.2 加载配置文件 conf/server.xml
    转化为inputSource
     没有配置文件,则log.debug(sm.getString("catalina.configFail", new Object[]{file}), var25);
    加载conf/server.xml   server-embed.xml
    将该类加入到digester栈顶digester.push(this);,解析 digester.parse(inputSource); xml文件
    label251: {
            try {
                try {
                    file = this.configFile();
                    inputStream = new FileInputStream(file);
                    inputSource = new InputSource(file.toURI().toURL().toString());
                } catch (Exception var25) {
                    if(log.isDebugEnabled()) {
                        log.debug(sm.getString("catalina.configFail", new Object[]{file}), var25);
                    }
                }

                if(inputStream == null) {
                    try {
                        inputStream = this.getClass().getClassLoader().getResourceAsStream(this.getConfigFile());
                        inputSource = new InputSource(this.getClass().getClassLoader().getResource(this.getConfigFile()).toString());
                    } catch (Exception var26) {
                        if(log.isDebugEnabled()) {
                            log.debug(sm.getString("catalina.configFail", new Object[]{this.getConfigFile()}), var26);
                        }
                    }
                }

                if(inputStream == null) {
                    try {
                        inputStream = this.getClass().getClassLoader().getResourceAsStream("server-embed.xml");
                        inputSource = new InputSource(this.getClass().getClassLoader().getResource("server-embed.xml").toString());
                    } catch (Exception var27) {
                        if(log.isDebugEnabled()) {
                            log.debug(sm.getString("catalina.configFail", new Object[]{"server-embed.xml"}), var27);
                        }
                    }
                }

                if(inputStream != null && inputSource != null) {
                    try {
                        inputSource.setByteStream((InputStream)inputStream);
                        digester.push(this);
                        digester.parse(inputSource);
                        break label251;
                    } catch (SAXParseException var28) {
                        log.warn("Catalina.start using " + this.getConfigFile() + ": " + var28.getMessage());
                        return;
                    } catch (Exception var29) {
                        log.warn("Catalina.start using " + this.getConfigFile() + ": ", var29);
                        return;
                    }
                }
         关闭IO流
         3.3.调用Server方法
         this.getServer().setCatalina(this);
        this.getServer().setCatalinaHome(Bootstrap.getCatalinaHomeFile());
        this.getServer().setCatalinaBase(Bootstrap.getCatalinaBaseFile());
        3.3.1 初始化StandardServer类  server,并传入值
        this.initStreams();
        this.getServer().init();  //初始化生命周期
        3.3.1 this.getServer().init()
        public interface Lifecycle    void init() throws LifecycleException;
        其实现类:
            this.setStateInternal(LifecycleState.INITIALIZING, (Object)null, false);   //设置生命周期状态
            this.initInternal();
            this.setStateInternal(LifecycleState.INITIALIZED, (Object)null, false)
       
        load完成
        


        4.start
        获取加载器
        4.1 this.initClassLoaders();
            Thread.currentThread().setContextClassLoader(this.catalinaLoader);
            SecurityClassLoad.securityClassLoad(this.catalinaLoader);
            if(log.isDebugEnabled()) {
            log.debug("Loading startup class");
            }
            //调用方法父类加载器
            Class startupClass = this.catalinaLoader.loadClass("org.apache.catalina.startup.Catalina");
            Object startupInstance = startupClass.newInstance();
            if(log.isDebugEnabled()) {
               log.debug("Setting startup class properties");
            }

            String methodName = "setParentClassLoader";
            Class[] paramTypes = new Class[]{Class.forName("java.lang.ClassLoader")};
            Object[] paramValues = new Object[]{this.sharedLoader};
            Method method = startupInstance.getClass().getMethod(methodName, paramTypes);
            method.invoke(startupInstance, paramValues);
            this.catalinaDaemon = startupInstance;

        4.2 调用映射
            Method method = this.catalinaDaemon.getClass().getMethod("start", (Class[])null);
            method.invoke(this.catalinaDaemon, (Object[])null);
        调用Catalina.start()
            if(this.getServer() == null) {
            this.load();
        } 
        4.2.1 调用生命周期中的start()方法
        4.2.2 创建钩子程序
          if(this.shutdownHook == null) {
                    this.shutdownHook = new Catalina.CatalinaShutdownHook();
                }

                Runtime.getRuntime().addShutdownHook(this.shutdownHook);
                LogManager logManager = LogManager.getLogManager();
                if(logManager instanceof ClassLoaderLogManager) {
                    ((ClassLoaderLogManager)logManager).setUseShutdownHook(false);
                }
        4.2.3 唤醒,停止
          if(this.await) {
                this.await();
                this.stop();
            }
          4.2.3.1  关闭过程
            try {
                    this.awaitThread = Thread.currentThread();

                    while(!this.stopAwait) {
                        try {
                            Thread.sleep(10000L);
                        } catch (InterruptedException var64) {
                            ;
                        }
                    }
                } finally {
                    this.awaitThread = null;
                }

            } else {
                try {
                    this.awaitSocket = new ServerSocket(this.port, 1, InetAddress.getByName(this.address));
                } catch (IOException var67) {
                    log.error("StandardServer.await: create[" + this.address + ":" + this.port + "]: ", var67);
                    return;
                }

                boolean var32 = false;

                ServerSocket serverSocket;
                try {
                    var32 = true;
                    this.awaitThread = Thread.currentThread();

                    while(true) {
                        if(this.stopAwait) {
                            var32 = false;
                            break;
                        }

                        serverSocket = this.awaitSocket;
                        if(serverSocket == null) {
                            var32 = false;
                            break;
                        }

                        Socket socket = null;
                        StringBuilder command = new StringBuilder();

                        label615: {
                            label614: {
                                try {
                                    label638: {
                                        long acceptStartTime = System.currentTimeMillis();

                                        InputStream match;
                                        try {
                                            socket = serverSocket.accept();
                                            socket.setSoTimeout(10000);
                                            match = socket.getInputStream();
                                        } catch (SocketTimeoutException var69) {
                                            log.warn(sm.getString("standardServer.accept.timeout", new Object[]{Long.valueOf(System.currentTimeMillis() - acceptStartTime)}), var69);
                                            continue;
                                        } catch (AccessControlException var70) {
                                            log.warn("StandardServer.accept security exception: " + var70.getMessage(), var70);
                                            continue;
                                        } catch (IOException var71) {
                                            if(this.stopAwait) {
                                                break label614;
                                            }

                                            log.error("StandardServer.await: accept: ", var71);
                                            break label638;
                                        }

                                        int expected;
                                        for(expected = 1024; expected < this.shutdown.length(); expected += this.random.nextInt() % 1024) {
                                            if(this.random == null) {
                                                this.random = new Random();
                                            }
                                        }

                                        while(true) {
                                            if(expected <= 0) {
                                                break label615;
                                            }

                                            boolean ch = true;

                                            int var75;
                                            try {
                                                var75 = match.read();
                                            } catch (IOException var66) {
                                                log.warn("StandardServer.await: read: ", var66);
                                                var75 = -1;
                                            }

                                            if(var75 < 32 || var75 == 127) {
                                                break label615;
                                            }

                                            command.append((char)var75);
                                            --expected;
                                        }
                                    }
                                } finally {
                                    try {
                                        if(socket != null) {
                                            socket.close();
                                        }
                                    } catch (IOException var63) {
                                        ;
                                    }

                                }

                                var32 = false;
                                break;
                            }

                            var32 = false;
                            break;
                        }

                        boolean var74 = command.toString().equals(this.shutdown);
                        if(var74) {
                            log.info(sm.getString("standardServer.shutdownViaPort"));
                            var32 = false;
                            break;
                        }

                        log.warn("StandardServer.await: Invalid command \'" + command.toString() + "\' received");
                    }
                } finally {
                    if(var32) {
                        ServerSocket serverSocket1 = this.awaitSocket;
                        this.awaitThread = null;
                        this.awaitSocket = null;
                        if(serverSocket1 != null) {
                            try {
                                serverSocket1.close();
                            } catch (IOException var62) {
                                ;
                            }
                        }

                    }
                }

                serverSocket = this.awaitSocket;
                this.awaitThread = null;
                this.awaitSocket = null;
                if(serverSocket != null) {
                    try {
                        serverSocket.close();
                    } catch (IOException var65) {
                        ;
                    }
                }

            }
           关闭过程相当于在启动中创建一个线程等待,等到发送关闭命令以后Socket捕获这个线程然后启动关闭
      程序。
        4.2.3.2 关闭钩子程序
             Runtime.getRuntime().removeShutdownHook(this.shutdownHook);
                LogManager e = LogManager.getLogManager();
                if(e instanceof ClassLoaderLogManager) {
                    ((ClassLoaderLogManager)e).setUseShutdownHook(true);
                }
            }
     

转载于:https://my.oschina.net/puzhiyuan/blog/870292

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值