tomcat6学习笔记——Bootstrap、Catalina

本文详细阐述了Tomcat启动过程中的关键步骤,包括Bootstrap中的main方法、init方法、load方法以及start方法的作用,以及如何通过反射调用Catalina对象进行启动。同时解释了配置文件server.xml的解析流程和组件对象的建立。
前面了解过tomcat的启动脚本,Tomcat的启动是Bootstrap中的main方法

public static void main(String args[]) {

if (daemon == null) {
daemon = new Bootstrap();
try {
daemon.init();
} catch (Throwable t) {
t.printStackTrace();
return;
}
}

// 根据不同的命令参数执行
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);
daemon.load(args);
daemon.start();
} else if (command.equals("stop")) {
daemon.stopServer(args);
} else {
log.warn("Bootstrap: command \"" + command + "\" does not exist.");
}
} catch (Throwable t) {
t.printStackTrace();
}

}


首先是init()

public void init()
throws Exception
{

// Set Catalina path
// 设置catalina_home属性,tomcat启动脚本里有通过-Dcatalina.home设置
setCatalinaHome();
// 设置catalina_base属性,运行多实例的时候该目录与catalina_home不同
setCatalinaBase();

// 初始化classloader,读取conf/catalina.properties,根据指定的repository创建classloader
// 有三个classloader 分别是common、catalina、shared,tomcat6中三个相同
initClassLoaders();
// 设置当前线程的classloader
Thread.currentThread().setContextClassLoader(catalinaLoader);
// 待研究
SecurityClassLoad.securityClassLoad(catalinaLoader);

// 以下通过反射调用Catalina中的方法
// Load our startup class and call its process() method
if (log.isDebugEnabled())
log.debug("Loading startup class");
Class startupClass =
catalinaLoader.loadClass
("org.apache.catalina.startup.Catalina");
Object startupInstance = startupClass.newInstance();

// Set the shared extensions class loader
if (log.isDebugEnabled())
log.debug("Setting startup class properties");
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;

}


然后load,实际上市通过反射调用了catalina的load方法。
1、找到config file(server.xml)
2、创建digester,解析server.xml,生成各组件对象(Server、Service、Container、Connector等)以及建立相互之间的关系。

// Configure the actions we will be using
digester.addObjectCreate("Server",
"org.apache.catalina.core.StandardServer",
"className");
digester.addSetProperties("Server");
digester.addSetNext("Server",
"setServer",
"org.apache.catalina.Server");

digester.addObjectCreate("Server/GlobalNamingResources",
"org.apache.catalina.deploy.NamingResources");
digester.addSetProperties("Server/GlobalNamingResources");
digester.addSetNext("Server/GlobalNamingResources",
"setGlobalNamingResources",
"org.apache.catalina.deploy.NamingResources");

digester.addObjectCreate("Server/Listener",
null, // MUST be specified in the element
"className");
digester.addSetProperties("Server/Listener");
digester.addSetNext("Server/Listener",
"addLifecycleListener",
"org.apache.catalina.LifecycleListener");

digester.addObjectCreate("Server/Service",
"org.apache.catalina.core.StandardService",
"className");
digester.addSetProperties("Server/Service");
digester.addSetNext("Server/Service",
"addService",
"org.apache.catalina.Service");

digester.addObjectCreate("Server/Service/Listener",
null, // MUST be specified in the element
"className");
digester.addSetProperties("Server/Service/Listener");
digester.addSetNext("Server/Service/Listener",
"addLifecycleListener",
"org.apache.catalina.LifecycleListener");

//Executor
digester.addObjectCreate("Server/Service/Executor",
"org.apache.catalina.core.StandardThreadExecutor",
"className");
digester.addSetProperties("Server/Service/Executor");

digester.addSetNext("Server/Service/Executor",
"addExecutor",
"org.apache.catalina.Executor");


digester.addRule("Server/Service/Connector",
new ConnectorCreateRule());
digester.addRule("Server/Service/Connector",
new SetAllPropertiesRule(new String[]{"executor"}));
digester.addSetNext("Server/Service/Connector",
"addConnector",
"org.apache.catalina.connector.Connector");
// ...



最后start(),同样是在Bootstrap中通过反射调用catalina对象的start方法。

public void start() {

if (getServer() == null) {
load();
}

if (getServer() == null) {
log.fatal("Cannot start server. Server instance is not configured.");
return;
}

long t1 = System.nanoTime();

// Start the new server
if (getServer() instanceof Lifecycle) {
try {
((Lifecycle) getServer()).start();
} catch (LifecycleException e) {
log.error("Catalina.start: ", e);
}
}

long t2 = System.nanoTime();
if(log.isInfoEnabled())
log.info("Server startup in " + ((t2 - t1) / 1000000) + " ms");

try {
// Register shutdown hook
if (useShutdownHook) {
if (shutdownHook == null) {
shutdownHook = new CatalinaShutdownHook();
}
Runtime.getRuntime().addShutdownHook(shutdownHook);

// If JULI is being used, disable JULI's shutdown hook since
// shutdown hooks run in parallel and log messages may be lost
// if JULI's hook completes before the CatalinaShutdownHook()
LogManager logManager = LogManager.getLogManager();
if (logManager instanceof ClassLoaderLogManager) {
((ClassLoaderLogManager) logManager).setUseShutdownHook(
false);
}
}
} catch (Throwable t) {
// This will fail on JDK 1.2. Ignoring, as Tomcat can run
// fine without the shutdown hook.
}

if (await) {
await();
stop();
}

}

由于之间digester解析之间的push操作
digester.push(this);
digester.parse(inputSource);
解析时通过catalina的setServer方法将创建的StandardServer对象设置进去了,所以上面getServer方法返回digester创建的server对象,然后开始各组件的生命周期。Lifecycle、LifecycleListeners等。
Server start、通知监听器、Service start。。。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值