通过查看分析启动脚本,发现最终调用的入口是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. 为什么说Java中只有值传递?

    一.为什么说Java中只有值传递? 对于java中的参数传递方式中是否有引用传递这个话题,很多的人都认为Java中有引用传递,但是我个人的看法是,Java中只有值传递,没有引用传递. 那么关于对象的传 ...

  2. 常用cursor光标说明

    1.cursor语法: cursor : auto | crosshair | default | hand | move | help | wait | text | w-resize |s-res ...

  3. C4-ResNet-TF-小象cv-code

    https://blog.csdn.net/chaipp0607/article/details/75577305 https://blog.csdn.net/leastsq/article/deta ...

  4. iostat iotop 查看硬盘的读写、 free 查看内存的命令 、netstat 命令查看网络、tcpdump 命令

    iostat 命令 查看硬盘的使用情况: iostat iostat -x iotop 命令: 若没安装先安装: yum install iotop -y free 命令,用于查看内存的使用量: fr ...

  5. 编写一个漂亮的网站 第一课堂 基于vs编辑

    前台代码: <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"& ...

  6. java小知识,驼峰规则

    单词之间不以空格.连接号或者底线连结(例如不应写成:camel case.camel-case或camel_case形式).共有两种格式: 1.小驼峰式命名法(lower camel case): 第 ...

  7. win7启动老是自动进入Boot Menu无法进入系统

    如图 进入bios设置 点击startup 选择UEFI/Legacy Boot 那里的Legacy Only选项,选择另一个就会出现这种问题 正常进入系统

  8. HotSpot VM GC 的种类

    collector种类 GC在 HotSpot VM 5.0里有四种: incremental (sometimes called train) low pause collector已被废弃,不在介 ...

  9. quicklink 基本使用

    原理 使用可见性以及预取数据,同时充分利用浏览器的空闲时间,主要是解析href 以通过代码的选项指定需要加载的数据,当然其中 也添加了好多灵活的控制参数,方便我们使用,而且代码很小,压缩之后也就1kb ...

  10. 使用distillery&&docker 部署phoenix 应用

      distillery 发布了2.0 了,有好多的新的功能 config prodiver 进行环境变量的配置 appup tansforms 插件系统,方便在release 构建的时候进行修改 m ...