四. 开启容器
最后是Bootstrap#start()方法的内容了,start()方法结束后,Tomcat就启动成功了。
下面来看一下Bootstrap#start()的内容:
- public void start() throws Exception {
- if (catalinaDaemon == null)
- init();
- // 调用Catalina#start()
- Method method = catalinaDaemon.getClass().getMethod("start", (Class[]) null);
- method.invoke(catalinaDaemon, (Object[]) null);
- }
上述的方法调用了Catalina#start()方法,来进一步看一下:
- public void start() {
- if (server == null) {
- // server为空,重新载入
- load();
- }
- long t1 = System.nanoTime();
- // 开启新的Server
- if (server instanceof Lifecycle) {
- try {
- ((Lifecycle) server).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");
- // shutdown hook,不太清楚做什么的
- try {
- if (useShutdownHook) {
- if (shutdownHook == null) {
- shutdownHook = new CatalinaShutdownHook();
- }
- Runtime.getRuntime().addShutdownHook(shutdownHook);
- }
- } catch (Throwable t) {
- }
- // await,然后关闭
- if (await) {
- await();
- stop();
- }
- }
这个方法的核心就是在Server的开启这一步。还是来看一下StandardServer#start()
- public void start() throws LifecycleException {
- if (started) {
- log.debug(sm.getString("standardServer.start.started"));
- return;
- }
- // 通知"BEFORE_START_EVENT"事件
- lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);
- // 通知"START_EVENT"事件
- lifecycle.fireLifecycleEvent(START_EVENT, null);
- started = true;
- // 开启服务
- synchronized (services) {
- for (int i = 0; i < services.length; i++) {
- if (services[i] instanceof Lifecycle)
- ((Lifecycle) services[i]).start();
- }
- }
- // 通知"AFTER_START_EVENT"事件
- lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);
- }
这段代码非常清晰,先是发送"BEFORE_START_EVENT"事件,然后是"START_EVENT"事件,然后开启各个服务,最后发送"AFTER_START_EVENT"事件
其中StandardService#start()方法的源代码如下:
- public void start() throws LifecycleException {
- if (log.isInfoEnabled() && started) {
- log.info(sm.getString("standardService.start.started"));
- }
- if (!initialized)
- init();
- // 通知StandardService下面的监听器"BEFORE_START_EVENT"事件
- // 这里可以看一下server.xml和Catalina#createStartDigester(),事件监听器在Server和Service下面都有
- lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);
- if (log.isInfoEnabled())
- log.info(sm.getString("standardService.start.name", this.name));
- // 通知"START_EVENT"事件
- lifecycle.fireLifecycleEvent(START_EVENT, null);
- started = true;
- // 开启Container(Engine)
- if (container != null) {
- synchronized (container) {
- if (container instanceof Lifecycle) {
- ((Lifecycle) container).start();
- }
- }
- }
- // 开启executors
- synchronized (executors) {
- for (int i = 0; i < executors.size(); i++) {
- executors.get(i).start();
- }
- }
- // 开启Connectors
- synchronized (connectors) {
- for (int i = 0; i < connectors.length; i++) {
- if (connectors[i] instanceof Lifecycle)
- ((Lifecycle) connectors[i]).start();
- }
- }
- // 通知"AFTER_START_EVENT"事件
- lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);
- }
在此方法中可以看到,Tomcat的所有容器,服务等都已经启动完毕了。Tomcat的启动过程正式结束。