super.start()--->org.apache.catalina.core.ContainerBase#start()
/**
* Prepare for active use of the public methods of this Component.
*
* @exception LifecycleException if this component detects a fatal error
* that prevents it from being started
*/
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;
//這些為server.xml中配置應用元件的啟動,如果要了解的話
//可根據自己的配置進行檢視
// 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
//StandardHost容器的啟動,
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
//StandardPipeline的啟動(容器與容器間的管道)
if (pipeline instanceof Lifecycle)
((Lifecycle) pipeline).start();
// Notify our interested LifecycleListeners(裡面将會對HostConfig進行啟動,并且部暑webapps)
lifecycle.fireLifecycleEvent(START_EVENT, null);
// Start our thread
threadStart();
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);
}
StandardHost#start
/**
* Start this host.
*
* @exception LifecycleException if this component detects a fatal error
* that prevents it from being started
*/
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"));
}
//傳回到以上的containerBase#start執行pipeline
//pipeline是容器與容器間的橋梁(管道),在每一個容器中執行這一步,都為自己的容器添加相應的valve
super.start();
}
StandardPipeline#start
/**
* Prepare for active use of the public methods of this Component.
*
* @exception LifecycleException if this component detects a fatal error
* that prevents it from being started
*/
public synchronized void start() throws LifecycleException {
// Validate and update our current component state
if (started)
throw new LifecycleException
(sm.getString("standardPipeline.alreadyStarted"));
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);
started = true;
// Start the Valves in our pipeline (including the basic), if any
Valve current = first;
if (current == null) {
current = basic;
}
while (current != null) {
//ErrorReportValve StandardHostValve兩個閥門
if (current instanceof Lifecycle)
((Lifecycle) current).start();
//注冊閥門,
registerValve(current);
current = current.getNext();
}
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(START_EVENT, null);
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);
}
HostConfig#lifecycleEvent方法下的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);
}
//StandardHost判斷
if (host.getDeployOnStartup())
//部暑webapps
deployApps();
}
HostConfig#deployApps
/**
* Deploy applications for any directories or WAR files that are found
* in our "application root" directory.
*/
protected void deployApps() {
//webapps,以下方法見名知義
File appBase = appBase();
File configBase = configBase();
// Deploy XML descriptors from configBase
deployDescriptors(configBase, configBase.list());
// Deploy WARs, and loop if additional descriptors are found
deployWARs(appBase, appBase.list());
// Deploy expanded folders
deployDirectories(appBase, appBase.list());
}