1.Bootstrap初始化后,执行start(),调用Catalina.start():
/**
* Start a new server instance.
*/
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();
}
}
2.((Lifecycle) getServer()).start();调用StandardServer.start();
/**
* Prepare for the beginning of active use of the public methods of this
* component. This method should be called before any of the public
* methods of this component are utilized. It should also send a
* LifecycleEvent of type START_EVENT to any registered listeners.
*
* @exception LifecycleException if this component detects a fatal error
* that prevents this component from being used
*/
public void start() throws LifecycleException {
// Validate and update our current component state
if (started) {
log.debug(sm.getString("standardServer.start.started"));
return;
}
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);
lifecycle.fireLifecycleEvent(START_EVENT, null);
started = true;
// Start our defined Services
synchronized (services) {
for (int i = 0; i < services.length; i++) {
if (services[i] instanceof Lifecycle)
((Lifecycle) services[i]).start();
}
}
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);
}
3.遍历执行((Lifecycle) services[i]).start();调用与其相关的所有StandardService.start();
public void start() throws LifecycleException {
// Validate and update our current component state
if (started) {
if (log.isInfoEnabled()) {
log.info(sm.getString("standardService.start.started"));
}
return;
}
if( ! initialized )
init();
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);
if(log.isInfoEnabled())
log.info(sm.getString("standardService.start.name", this.name));
lifecycle.fireLifecycleEvent(START_EVENT, null);
started = true;
// Start our defined Container first
if (container != null) {
synchronized (container) {
if (container instanceof Lifecycle) {
((Lifecycle) container).start();
}
}
}
synchronized (executors) {
for ( int i=0; i<executors.size(); i++ ) {
executors.get(i).start();
}
}
// Start our defined Connectors second
synchronized (connectors) {
for (int i = 0; i < connectors.length; i++) {
try {
((Lifecycle) connectors[i]).start();
} catch (Exception e) {
log.error(sm.getString(
"standardService.connector.startFailed",
connectors[i]), e);
}
}
}
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);
}
4.这里先后启动StandardEngine和Connector。
1)执行((Lifecycle) container).start();即StandardEngine.start()。
public void start() throws LifecycleException {
if( started ) {
return;
}
if( !initialized ) {
init();
}
// Look for a realm - that may have been configured earlier.
// If the realm is added after context - it'll set itself.
if( realm == null ) {
ObjectName realmName=null;
try {
realmName=new ObjectName( domain + ":type=Realm");
if( mserver.isRegistered(realmName ) ) {
mserver.invoke(realmName, "init",
new Object[] {},
new String[] {}
);
}
} catch( Throwable t ) {
log.debug("No realm for this engine " + realmName);
}
}
// Log our server identification information
//System.out.println(ServerInfo.getServerInfo());
if(log.isInfoEnabled())
log.info( "Starting Servlet Engine: " + ServerInfo.getServerInfo());
if( mbeans != null ) {
try {
Registry.getRegistry(null, null)
.invoke(mbeans, "start", false);
} catch (Exception e) {
log.error("Error in start() for " + mbeansFile, e);
}
}
// Standard container startup
super.start();
}
StandardEngine在《组件的初始化》中未参与初始化,所以会执行StandardEngine.init(),不过这个init也没干什么事。
最后一行super.start()调用的是ContainerBase.start():
public synchronized void start() throws LifecycleException {
// Validate and update our current component state
if (started) {
if(log.isInfoEnabled())
log.info(sm.getString("containerBase.alreadyStarted", logName()));
return;
}
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);
started = true;
// Start our subordinate components, if any
if ((loader != null) && (loader instanceof Lifecycle))
((Lifecycle) loader).start();
logger = null;
getLogger();
if ((logger != null) && (logger instanceof Lifecycle))
((Lifecycle) logger).start();
if ((manager != null) && (manager instanceof Lifecycle))
((Lifecycle) manager).start();
if ((cluster != null) && (cluster instanceof Lifecycle))
((Lifecycle) cluster).start();
if ((realm != null) && (realm instanceof Lifecycle))
((Lifecycle) realm).start();
if ((resources != null) && (resources instanceof Lifecycle))
((Lifecycle) resources).start();
// Start our child containers, if any
Container children[] = findChildren();
for (int i = 0; i < children.length; i++) {
if (children[i] instanceof Lifecycle)
((Lifecycle) children[i]).start();
}
// Start the Valves in our pipeline (including the basic), if any
if (pipeline instanceof Lifecycle)
((Lifecycle) pipeline).start();
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(START_EVENT, null);
// Start our thread
threadStart();
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);
}
StandarHost、StandardContext都会继承这个ContainerBase,且他们的启动最终也是交给这个ContainerBase来处理。所以,有必要了解下这个ContainerBase,start方法里边出镜率最高的应该是lifecycle:
protected LifecycleSupport lifecycle = new LifecycleSupport(this);
它是直接在ContainerBase的属性中new出来的,参数是基类对象,StandardEngine实例化的时候,这个this就是StandardEngine对象。(这个应该也是一种设计模式?)LifecycleSupport有三个重要的方法addLifecycleListener()、fireLifecycleEvent()、removeLifecycleListener()。addLifecycleListener在初始化的时候经常用到,它把所有相关的监听器都加到LifecycleSupport的listeners数组中。
上面代码lifecycle出现的时候都是执行fireLifecycleEvent():
/**
* Notify all lifecycle event listeners that a particular event has
* occurred for this Container. The default implementation performs
* this notification synchronously using the calling thread.
*
* @param type Event type
* @param data Event data
*/
public void fireLifecycleEvent(String type, Object data) {
if (Lifecycle.INIT_EVENT.equals(type)) {
state = "INITIALIZED";
} else if (Lifecycle.BEFORE_START_EVENT.equals(type)) {
state = "STARTING_PREP";
} else if (Lifecycle.START_EVENT.equals(type)) {
state = "STARTING";
} else if (Lifecycle.AFTER_START_EVENT.equals(type)) {
state = "STARTED";
} else if (Lifecycle.BEFORE_STOP_EVENT.equals(type)) {
state = "STOPPING_PREP";
} else if (Lifecycle.STOP_EVENT.equals(type)) {
state = "STOPPING";
} else if (Lifecycle.AFTER_STOP_EVENT.equals(type)) {
state = "STOPPED";
} else if (Lifecycle.DESTROY_EVENT.equals(type)) {
state = "DESTROYED";
}
LifecycleEvent event = new LifecycleEvent(lifecycle, type, data);
LifecycleListener interested[] = listeners;
for (int i = 0; i < interested.length; i++)
interested[i].lifecycleEvent(event);
}
经过LifecycleEvent的封装后(这又是一个设计模式?)将会调用各个LifecycleListener.lifecycleEvent()。回过头来看看StandardEngine绑了几个LifecycleListener,具体有多少要看看配置文件,但至少有这个EngineConfig (见《Engine的实例化》)。EngineConfig.lifecycleEvent():
public void lifecycleEvent(LifecycleEvent event) {
// Identify the engine we are associated with
try {
engine = (Engine) event.getLifecycle();
} catch (ClassCastException e) {
log.error(sm.getString("engineConfig.cce", event.getLifecycle()), e);
return;
}
// Process the event that has occurred
if (event.getType().equals(Lifecycle.START_EVENT))
start();
else if (event.getType().equals(Lifecycle.STOP_EVENT))
stop();
}
经过这样传递,StandardEngine继承的ContainerBase.start()中,lifecycle.fireLifecycleEvent(START_EVENT, null);最终会执行EngineConfig.start():
protected void start() {
if (engine.getLogger().isDebugEnabled())
engine.getLogger().debug(sm.getString("engineConfig.start"));
}
尼玛。。。绕这么多就为了记个日志。不过这一步会在((Lifecycle) children[i]).start()之后执行。
(1)((Lifecycle) children[i]).start();调用StandardHost.start():
public synchronized void start() throws LifecycleException {
if( started ) {
return;
}
if( ! initialized )
init();
// Look for a realm - that may have been configured earlier.
// If the realm is added after context - it'll set itself.
if( realm == null ) {
ObjectName realmName=null;
try {
realmName=new ObjectName( domain + ":type=Realm,host=" + getName());
if( mserver.isRegistered(realmName ) ) {
mserver.invoke(realmName, "init",
new Object[] {},
new String[] {}
);
}
} catch( Throwable t ) {
log.debug("No realm for this host " + realmName);
}
}
// Set error report valve
if ((errorReportValveClass != null)
&& (!errorReportValveClass.equals(""))) {
try {
boolean found = false;
if(errorReportValveObjectName != null) {
ObjectName[] names =
((StandardPipeline)pipeline).getValveObjectNames();
for (int i=0; !found && i<names.length; i++)
if(errorReportValveObjectName.equals(names[i]))
found = true ;
}
if(!found) {
Valve valve = (Valve) Class.forName(errorReportValveClass)
.newInstance();
addValve(valve);
errorReportValveObjectName = ((ValveBase)valve).getObjectName() ;
}
} catch (Throwable t) {
log.error(sm.getString
("standardHost.invalidErrorReportValveClass",
errorReportValveClass), t);
}
}
if(log.isDebugEnabled()) {
if (xmlValidation)
log.debug(sm.getString("standardHost.validationEnabled"));
else
log.debug(sm.getString("standardHost.validationDisabled"));
}
super.start();
}
同样的super.start()会执行ContainerBase.start(),而ContainerBase.start()会执行它children.start()即StandardContext.start()。然后再执行其所有绑定LifecycleListener,其中HostConfig很重要,会负责部署所有项目,HostConfig.start():
/**
* Process a "start" event for this Host.
*/
public void start() {
if (log.isDebugEnabled())
log.debug(sm.getString("hostConfig.start"));
try {
ObjectName hostON = new ObjectName(host.getObjectName());
oname = new ObjectName
(hostON.getDomain() + ":type=Deployer,host=" + host.getName());
Registry.getRegistry(null, null).registerComponent
(this, oname, this.getClass().getName());
} catch (Exception e) {
log.error(sm.getString("hostConfig.jmx.register", oname), e);
}
if (host.getDeployOnStartup())
deployApps();
}
StandardContext.start()也是先把children.start(),再执行ContextConfig.start(),conf/server.xml并没有配置相关的Context所以不会去执行children.start()。
但是会在HostConfig中部署项目的时候去将项目Context加到host的children中。
ContextConfig会调用WebRuleSet.addRuleInstances():解析web.xml。
这些ContainerBase类的设计:
不断的先调用children.start(),在调用自身的listener的设计有点像递归。(肯定是一种设计模式!)
2)执行((Lifecycle) connectors[i]).start();即Connector.start()。
public void start() throws LifecycleException {
if( !initialized )
initialize();
// Validate and update our current state
if (started ) {
if(log.isInfoEnabled())
log.info(sm.getString("coyoteConnector.alreadyStarted"));
return;
}
lifecycle.fireLifecycleEvent(START_EVENT, null);
started = true;
// We can't register earlier - the JMX registration of this happens
// in Server.start callback
if ( this.oname != null ) {
// We are registred - register the adapter as well.
try {
Registry.getRegistry(null, null).registerComponent
(protocolHandler, createObjectName(this.domain,"ProtocolHandler"), null);
} catch (Exception ex) {
log.error(sm.getString
("coyoteConnector.protocolRegistrationFailed"), ex);
}
} else {
if(log.isInfoEnabled())
log.info(sm.getString
("coyoteConnector.cannotRegisterProtocol"));
}
try {
protocolHandler.start();
} catch (Exception e) {
String errPrefix = "";
if(this.service != null) {
errPrefix += "service.getName(): \"" + this.service.getName() + "\"; ";
}
throw new LifecycleException
(errPrefix + " " + sm.getString
("coyoteConnector.protocolHandlerStartFailed", e));
}
if( this.domain != null ) {
mapperListener.setDomain( domain );
//mapperListener.setEngine( service.getContainer().getName() );
mapperListener.init();
try {
ObjectName mapperOname = createObjectName(this.domain,"Mapper");
if (log.isDebugEnabled())
log.debug(sm.getString(
"coyoteConnector.MapperRegistration", mapperOname));
Registry.getRegistry(null, null).registerComponent
(mapper, mapperOname, "Mapper");
} catch (Exception ex) {
log.error(sm.getString
("coyoteConnector.protocolRegistrationFailed"), ex);
}
}
}
protocolHandler.start();从《Connector的实例化》中可知,8080端口对应的protocolHandler为Http11Protocol对象。Http11Protocol.start():
public void start() throws Exception {
if (this.domain != null) {
try {
tpOname = new ObjectName
(domain + ":" + "type=ThreadPool,name=" + getName());
Registry.getRegistry(null, null)
.registerComponent(endpoint, tpOname, null );
} catch (Exception e) {
log.error("Can't register endpoint");
}
rgOname=new ObjectName
(domain + ":type=GlobalRequestProcessor,name=" + getName());
Registry.getRegistry(null, null).registerComponent
( cHandler.global, rgOname, null );
}
try { endpoint.start();
} catch (Exception ex) {
log.error(sm.getString("http11protocol.endpoint.starterror"), ex);
throw ex;
}
if (log.isInfoEnabled())
log.info(sm.getString("http11protocol.start", getName()));
}
endpoint.start();调用的是JIoEndpoint.start():
public void start()
throws Exception {
// Initialize socket if not done before
if (!initialized) {
init();
}
if (!running) {
running = true;
paused = false;
// Create worker collection
if (executor == null) {
workers = new WorkerStack(maxThreads);
}
// Start acceptor threads
for (int i = 0; i < acceptorThreadCount; i++) {
Thread acceptorThread = new Thread(new Acceptor(), getName() + "-Acceptor-" + i);
acceptorThread.setPriority(threadPriority);
acceptorThread.setDaemon(daemon);
acceptorThread.start();
}
}
}
acceptorThread.start();调用的是Acceptor.run():
/**
* Server socket acceptor thread.
*/
protected class Acceptor implements Runnable {
/**
* The background thread that listens for incoming TCP/IP connections and
* hands them off to an appropriate processor.
*/
public void run() {
// Loop until we receive a shutdown command
while (running) {
// Loop if endpoint is paused
while (paused) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// Ignore
}
}
// Accept the next incoming connection from the server socket
try {
Socket socket = serverSocketFactory.acceptSocket(serverSocket);
serverSocketFactory.initSocket(socket);
// Hand this socket off to an appropriate processor
if (!processSocket(socket)) {
// Close socket right away
try {
socket.close();
} catch (IOException e) {
// Ignore
}
}
}catch ( IOException x ) {
if ( running ) log.error(sm.getString("endpoint.accept.fail"), x);
} catch (Throwable t) {
log.error(sm.getString("endpoint.accept.fail"), t);
}
// The processor will recycle itself when it finishes
}
}
}
线程被阻塞,监听端口上的请求。各组件start完成,tomcat已启动。