Tomcat运行入口类BootStrap的入口方法,即启动方法;将Tomcat的启动分为了两部分 init 和 start
- init:初始化阶段,即后面要依次调用的是各组件的初始化方法
- InitInternal:Standard~,Connector;因为他们继承了LifeCycleBase,里面用模板模式实现了init方法
- init:ProtocolHandler是enum,Endpoint是抽象类;他们都自己定义了init,而不是LifeCycle的init
- start:运行阶段,即后面要依次调用各组件的start方法
- startInternal:Standard~,Connector;因为他们继承了LifeCycleBase,里面用模板模式实现了start方法
- start:ProtocolHandler是enum,Endpoint是抽象类;他们都自己定义了start,而不是LifeCycle的start
public static void main(String args[]) {
//1.初始化阶段 init()
if (daemon == null) {
// Don't set daemon until init() has completed
Bootstrap bootstrap = new Bootstrap();
try {
// 调用init()初始化BootStrap
bootstrap.init();
} catch (Throwable t) {
handleThrowable(t);
t.printStackTrace();
return;
}
// 将守护线程bootstop赋给守护线程daemon
daemon = bootstrap;
} else {
Thread.currentThread().setContextClassLoader(daemon.catalinaLoader);
}
//2.运行阶段 start()
try {
String command = "start";
if (args.length > 0) {
command = args[args.length - 1];
}
if (command.equals("startd")) {
args[args.length - 1] = "start";
// deamon.load(args),实际上会去调用Catalina#load(args)方法,
// 会去初始化一些资源,优先加载conf/server.xml,找不到再去加载server-embed.xml;
// 此外,load方法还会初始化Server
daemon.load(args);
// daemon.start(),实例上是调用Catalina.start()
daemon.start();
// 输入stop命令就停止
} 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 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);
}
}