导入 idea

ant ide-intellij 

会下载点依赖在 %userprofile%\tomcat-build-libs

科学上网可以加 -Dproxy.use=true -Dproxy.host=127.0.0.1 -Dproxy.port=10808

关键代码逻辑

作为入口,通过反射调用 Catalina 的 setAwait、load、start

  1. 创建 ClassLoader(如 CommonClassLoader),加载 catalina.jar 等内部 JAR

  2. 使用 Thread.currentThread().setContextClassLoader() 设置该加载器

  3. 通过反射调用 org.apache.catalina.startup.Catalina.start(),确保 Catalina 类由 CommonClassLoader 加载,而非系统类加载器


三个自定义类加载器,commonLoader、catalinaLoader、sharedLoader

加载类的路径不同,每种类加载都有自己的职责范围,配置默认在conf/catalina.properties

Thread.currentThread().setContextClassLoader(daemon.catalinaLoader);

破坏双亲委派的一贯做法

catalina.home和catalina.base

catalina.home是Tomcat安装目录,包含bin和lib

catalina.base是实例目录,包含conf、logs、webapps等,不指定则和catalina.home相同

代码

org.apache.catalina.startup.Bootstrap

main()

Bootstrap bootstrap = new Bootstrap();
bootstrap.init();

String command = "start";

if (command.equals("startd")) {
    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();
    if (null == daemon.getServer()) {
        System.exit(1);
    }
} else if (command.equals("stop")) {
    daemon.stopServer(args);
    ...

创建 Bootstrap 对象,调用 init ()初始化,根据启动参数,分别调用 Bootstrap 对象的不同方法

static 块

private static final File catalinaBaseFile;
private static final File catalinaHomeFile;

System.setProperty("catalina.base");
System.setProperty("catalina.home");

getCanonicalFile 可以根据操作系统,解析得到规范的唯一路径名,如../ ./等,getCanonicalFile可以正确解析,而getAbsoluteFile不会

start()

daemon.setAwait(true);
daemon.load(args);
daemon.start();

通过反射去调用 init 方法里初始化过的 Catalina 对象的同名的方法

setAwait

调用Server的await()开启线程,监听默认8005端口SHUTDOWN指令后,调用Server的stop和destroy,停止并销毁Server下的所有子容器和组件

时序

sequenceDiagram
    participant startup.bat
    participant BootStrap
    participant Catalina
    participant Server
    participant Service
    participant Executor
    participant Engine
    participant Host
    participant Context
    participant Connector
    participant ProtocolHandler

    startup.bat ->> BootStrap: main()
    activate startup.bat
    deactivate startup.bat
    activate BootStrap
    BootStrap ->> BootStrap: init
    BootStrap ->> BootStrap: load
 	BootStrap ->> Catalina: load
 	activate BootStrap
    deactivate BootStrap
    activate Catalina
	Catalina ->> Server: init
    deactivate Catalina
    activate Server
    Server ->> Service: init
	deactivate Server
	activate Service
    Service ->> Executor: init
    activate Executor
    deactivate Executor
    Service ->> Engine: init
 	activate Engine
    Engine ->> Host: init
    deactivate Engine
    activate Host 
    Host ->> Context: init
    deactivate Host
    activate Context
    deactivate Context 
    Service ->> Connector: init
    activate Connector
    deactivate Service
    Connector ->> ProtocolHandler: init
    activate ProtocolHandler
    deactivate ProtocolHandler
    deactivate Connector 
    
    BootStrap ->> Catalina: start
    activate BootStrap
    deactivate BootStrap
    activate Catalina
    Catalina ->> Server: start
    deactivate Catalina
    activate Server
    Server ->> Service: start
    deactivate Server
    activate Service
    Service ->> Executor: start
    activate Executor
	deactivate Executor
    Service ->> Engine: start
	activate Engine	
    Engine ->> Host: start
    deactivate Engine
    activate Host 
    Host ->> Context: start
    deactivate Host
    activate Context
    deactivate Context
    Service ->> Connector: start
    deactivate Service
    activate Connector
    Connector ->> ProtocolHandler: start
    activate ProtocolHandler
    deactivate ProtocolHandler
    deactivate Connector 
    deactivate BootStrap
 

深入

server.xml解析,Server一键初始化,一键启停涉及到Tomcat的生命周期管理