来源
本文整理自 <Tomcat内核设计剖析>、<Tomcat结构解析> 加上自己的理解、源码来自 Tomcat8.5 版本
// org.apache.catalina.startup.Bootstrap
public static void main(String args[]) {
if (daemon == null) {
// 先创建一个 bootstrap 实例
Bootstrap bootstrap = new Bootstrap();
try {
// 初始化ClassLoader:
// ClassLoader commonLoader = null;
// ClassLoader catalinaLoader = null; 绑定到当前线程上
// ClassLoader sharedLoader = null;
// catalinaLoader类加载器创建Catalina实例,赋值给catalinaDaemon
bootstrap.init();
} catch (Throwable t) {
handleThrowable(t);
t.printStackTrace();
return;
}
daemon = bootstrap;
} else {
Thread.currentThread().setContextClassLoader(daemon.catalinaLoader);
}
try {
// 默认执行 start 方法
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")) {
// 执行这个位置,【让主线程不退出】
// if the daemon should block: true
daemon.setAwait(true);
// 反射调用 catalinaDaemon#load 方法,根据server.xml 创建服务
daemon.load(args);
// 反射调用 catalinaDaemon#start 方法,启动服务
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.");
}
}
}
/**
* Initialize daemon.
* @throws Exception Fatal initialization error
*/
public void init() throws Exception {
initClassLoaders();
Thread.currentThread().setContextClassLoader(catalinaLoader);
SecurityClassLoad.securityClassLoad(catalinaLoader);
// 反射实例化Catalina类
Class<?> startupClass = catalinaLoader.loadClass("org.apache.catalina.startup.Catalina");
Object startupInstance = startupClass.getConstructor().newInstance();
String methodName = "setParentClassLoader";
Class<?> paramTypes[] = new Class[1];
paramTypes[0] = Class.forName("java.lang.ClassLoader");
Object paramValues[] = new Object[1];
paramValues[0] = sharedLoader;
Method method =
startupInstance.getClass().getMethod(methodName, paramTypes);
method.invoke(startupInstance, paramValues);
catalinaDaemon = startupInstance;
}
private void initClassLoaders() {
try {
commonLoader = createClassLoader("common", null);
if( commonLoader == null ) {
commonLoader=this.getClass().getClassLoader();
}
catalinaLoader = createClassLoader("server", commonLoader);
sharedLoader = createClassLoader("shared", commonLoader);
} catch (Throwable t) {
handleThrowable(t);
System.exit(1);
}
}