通过查看分析启动脚本,发现最终调用的入口是org.apache.catalina.startup包下面的Bootstrap#main

public static void main(String args[]) {

    if (daemon == null) {
// Don't set daemon until init() has completed
Bootstrap bootstrap = new Bootstrap();
try {
// 初始化类加载器(这主要是为了要把开发者编写的各种组件应用(WAR 、EAR 等)部署到容器中,并实现组件应用之间的隔离),创建Catalina实例
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);
// 通过反射调用Catalina的load方法,加载server.xml配置、初始化Server
daemon.load(args);
// 通过反射调用Catalina的start方法,开启服务、初始化并开启一系列组件、子容器
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);
} }

类org.apache.catalina.startup.Catalina#load分析:

public void load() {

    ......

    //初始化临时目录
initDirs(); // Before digester - it may be needed
//设置额外的系统属性
initNaming(); // Create and execute our Digester
//Digester是apache commons中的一种xml解析器,处理conf/server.xml
//在这个方法里,读取serverl.xml时通过反射实例化了standardServer对象
Digester digester = createStartDigester(); ...... try {
inputSource.setByteStream(inputStream);
digester.push(this);
//传入流到digester解析xml拼成对象
digester.parse(inputSource);
} catch (SAXParseException spe) {
log.warn("Catalina.start using " + getConfigFile() + ": " +
spe.getMessage());
return;
} catch (Exception e) {
log.warn("Catalina.start using " + getConfigFile() + ": " , e);
return;
} ...... getServer().setCatalina(this);
getServer().setCatalinaHome(Bootstrap.getCatalinaHomeFile());
getServer().setCatalinaBase(Bootstrap.getCatalinaBaseFile()); // Stream redirection
//自定义了System.out.PrintStream,写了一个子类SystemLogHandler继承PrintStream,便于多线程下的日志处理
initStreams(); // Start the new server
try {
//初始化Engine,Executor(用来在connector中管理线程池),Connector,mapperListener(用来监听container的变化的)
getServer().init();
} catch (LifecycleException e) {
if (Boolean.getBoolean("org.apache.catalina.startup.EXIT_ON_INIT_FAILURE")) {
throw new java.lang.Error(e);
} else {
log.error("Catalina.start", e);
}
} long t2 = System.nanoTime();
if(log.isInfoEnabled()) {
log.info("Initialization processed in " + ((t2 - t1) / 1000000) + " ms");
}
}

digester.parse解析xml创建对象的时候相关操作:

1.会绑定HostConfig到StandardHost的lifecycleListeners,然后执行StandardHost.ini时会调用HostConfig.deployApps去查找目录和XML找到Context

类org.apache.catalina.startup.Catalina#start分析:

public void start() {

    ......

    // Start the new server
try {
//启动Engine,Executor,Connector,mapperListener
getServer().start();
} catch (LifecycleException e) {
log.fatal(sm.getString("catalina.serverStartFail"), e);
try {
getServer().destroy();
} catch (LifecycleException e1) {
log.debug("destroy() failed for failed Server ", e1);
}
return;
} ...... //
if (await) {
//调用StandardServer的await方法
//创建socket连接的服务端对象ServerSocket;
//循环等待接收客户端发出的命令,如果接收到的命令与SHUTDOWN匹配(由于使用了equals,所以shutdown命令必须是大写的),那么退出循环等待 //执行shutdown.bat的时候,最终使用java命令执行了org.apache.catalina.startup.Bootstrap类中的main方法,参数是stop,
//通过调用Bootstrap的stopServer方法停止Tomcat,其实质是用反射调用catalinaDaemon(类型是Catalina)的stopServer方法。
//catalina通过创建Digester解析server.xml文件(此处只解析<Server>标签),以构造出Server容器(此时Server容器的子容器没有被实例化);
//从实例化的Server容器获取Server的socket监听端口和地址,然后创建Socket对象连接启动Tomcat时创建的ServerSocket,最后向ServerSocket发送SHUTDOWN命令。
//ServerSocket循环等待接收到SHUTDOWN命令后,最终调用stop方法停止Tomcat。
await();
stop();
}
}

tomcat源码 分析 Catalina的更多相关文章

  1. [Tomcat 源码分析系列] (二) : Tomcat 启动脚本-catalina.bat

    概述 Tomcat 的三个最重要的启动脚本: startup.bat catalina.bat setclasspath.bat 上一篇咱们分析了 startup.bat 脚本 这一篇咱们来分析 ca ...

  2. Tomcat源码分析

    前言: 本文是我阅读了TOMCAT源码后的一些心得. 主要是讲解TOMCAT的系统框架, 以及启动流程.若有错漏之处,敬请批评指教! 建议: 毕竟TOMCAT的框架还是比较复杂的, 单是从文字上理解, ...

  3. Tomcat源码分析之—具体启动流程分析

    从Tomcat启动调用栈可知,Bootstrap类的main方法为整个Tomcat的入口,在init初始化Bootstrap类的时候为设置Catalina的工作路径也就是Catalina_HOME信息 ...

  4. Tomcat源码分析--转

    一.架构 下面谈谈我对Tomcat架构的理解 总体架构: 1.面向组件架构 2.基于JMX 3.事件侦听 1)面向组件架构 tomcat代码看似很庞大,但从结构上看却很清晰和简单,它主要由一堆组件组成 ...

  5. tomcat 源码分析

    Tomcat源码分析——Session管理分析(下)    Tomcat源码分析——Session管理分析(上)     Tomcat源码分析——请求原理分析(下)     Tomcat源码分析——请 ...

  6. Tomcat源码分析——Session管理分析(下)

    前言 在<TOMCAT源码分析——SESSION管理分析(上)>一文中我介绍了Session.Session管理器,还以StandardManager为例介绍了Session管理器的初始化 ...

  7. Tomcat源码分析——Session管理分析(上)

    前言 对于广大java开发者而已,对于J2EE规范中的Session应该并不陌生,我们可以使用Session管理用户的会话信息,最常见的就是拿Session用来存放用户登录.身份.权限及状态等信息.对 ...

  8. Tomcat源码分析——请求原理分析(下)

    前言 本文继续讲解TOMCAT的请求原理分析,建议朋友们阅读本文时首先阅读过<TOMCAT源码分析——请求原理分析(上)>和<TOMCAT源码分析——请求原理分析(中)>.在& ...

  9. Tomcat源码分析——请求原理分析(中)

    前言 在<TOMCAT源码分析——请求原理分析(上)>一文中已经介绍了关于Tomcat7.0处理请求前作的初始化和准备工作,请读者在阅读本文前确保掌握<TOMCAT源码分析——请求原 ...

随机推荐

  1. 防止sql注入的函数addslashes()

    <?php $str = addslashes('Shanghai is the "biggest" city in China.'); echo($str); ?> ...

  2. shell 脚本中将输出内容赋值给一个变量时的换行问题

    for ((i=0; i<4; i++) do ....... done 如果使用 echo $a 输出变量,则变量中的 换行都会被忽略掉,所有内容输出到一行 而使用 echo "$a ...

  3. java-Random类

    1.Random类的概述和方法使用 * A:Random类的概述 * 此类用于产生随机数 * 如果用相同的种子创建两个 Random 实例,则对每个实例进行相同的方法调用序列,它们将生成并返回相同的数 ...

  4. Linux,IDS入侵防御系统

    https://www.comparitech.com/net-admin/network-intrusion-detection-tools/11 2018年的顶级入侵检测工具 https://op ...

  5. Go Example--通道选择器

    package main import ( "fmt" "time" ) func main() { c1 := make(chan string) c2 := ...

  6. webpack 搭建问题汇总

    总结一下遇到的问题: 1.这样的警告(The 'mode' option has not been set, webpack will fallback to 'production' for thi ...

  7. itcast-svn

    svn介绍 1.1     svn服务器的工作方式 数据   库  服务 概念   使用数据库,连接服务,服务操作库 独立服务器方式: svnserve 借助Apache方式: mod_dav_svn ...

  8. mysql-The-server-quit-without-updating-PID-file

    mysql 编译后执行 /etc/init.d/mysqld start 启动失败 提示:"The server quit without updating PID file" 排 ...

  9. python一些东西

    assert repr() >>> a ['d', 'c', 'c', 'f', 'a', 'a', 'b', 'c', 'd'] >>> sorted(a) [' ...

  10. ElasticSearch story(二)

    调优一个问题,碰到了一个坎:大家看一下下面两个字符串: 2018-10-16 18:01:34.000 abcdewfrwfe 2018-10-16 18:01:50.123 testAmily012 ...