前言
通過上面一篇關(guān)于生命周期的介紹,我們知道子類只要實(shí)現(xiàn)#initInternal()和#startInternal()方法即可。
initInternal()方法
protected void initInternal() throws LifecycleException {
super.initInternal();
//1. 初始化實(shí)用程序執(zhí)行程序
reconfigureUtilityExecutor(getUtilityThreadsInternal(utilityThreads));
//2. jmx相關(guān)
register(utilityExecutor, "type=UtilityExecutor");
// Register global String cache
// Note although the cache is global, if there are multiple Servers
// present in the JVM (may happen when embedding) then the same cache
// will be registered under multiple names
onameStringCache = register(new StringCache(), "type=StringCache");
// Register the MBeanFactory
MBeanFactory factory = new MBeanFactory();
factory.setContainer(this);
onameMBeanFactory = register(factory, "type=MBeanFactory");
// Register the naming resources
globalNamingResources.init();
// Populate the extension validator with JARs from common and shared
// class loaders
if (getCatalina() != null) {
ClassLoader cl = getCatalina().getParentClassLoader();
// Walk the class loader hierarchy. Stop at the system class loader.
// This will add the shared (if present) and common class loaders
while (cl != null && cl != ClassLoader.getSystemClassLoader()) {
if (cl instanceof URLClassLoader) {
URL[] urls = ((URLClassLoader) cl).getURLs();
for (URL url : urls) {
if (url.getProtocol().equals("file")) {
try {
File f = new File (url.toURI());
if (f.isFile() &&
f.getName().endsWith(".jar")) {
ExtensionValidator.addSystemResource(f);
}
} catch (URISyntaxException e) {
// Ignore
} catch (IOException e) {
// Ignore
}
}
}
}
cl = cl.getParent();
}
}
//3. 初始化所有的service
for (int i = 0; i < services.length; i++) {
services[i].init();
}
}
從上面可以看出#Server.init()方法主要初始化了所有的service,這里的services是在解析service.xml是設(shè)置進(jìn)去的。
digester.addObjectCreate("Server/Service",
"org.apache.catalina.core.StandardService",
"className");
digester.addSetProperties("Server/Service");
digester.addSetNext("Server/Service",
"addService",
"org.apache.catalina.Service");
createStartDigester()方法中可以看出,通過調(diào)用#Server.addService()方法設(shè)置了services:
public void addService(Service service) {
//1. 設(shè)置service的Server
service.setServer(this);
synchronized (servicesLock) {
Service results[] = new Service[services.length + 1];
System.arraycopy(services, 0, results, 0, services.length);
results[services.length] = service;
services = results;
//2. 如果狀態(tài)是start、before_start、after_start則直接啟動service
if (getState().isAvailable()) {
try {
service.start();
} catch (LifecycleException e) {
// Ignore
}
}
//3. 將此屬性更改報(bào)告給感興趣的監(jiān)聽器
support.firePropertyChange("service", null, service);
}
}
這里一般執(zhí)行到第二步狀態(tài)是NEW,所以不回去啟動service。
startInternal()方法
protected void startInternal() throws LifecycleException {
//1. 通知所有的監(jiān)聽器CONFIGURE_START_EVENT狀態(tài)事件,通常發(fā)生在BEFORE_START_EVENT之后和START_EVENT之前
fireLifecycleEvent(CONFIGURE_START_EVENT, null);
//2. 設(shè)置容器狀態(tài)為STARTING
setState(LifecycleState.STARTING);
globalNamingResources.start();
//3. 啟動services
synchronized (servicesLock) {
for (int i = 0; i < services.length; i++) {
services[i].start();
}
}
if (periodicEventDelay > 0) {
monitorFuture = getUtilityExecutor().scheduleWithFixedDelay(
new Runnable() {
@Override
public void run() {
startPeriodicLifecycleEvent();
}
}, 0, 60, TimeUnit.SECONDS);
}
}
流程比較簡單,就不做介紹了。
總結(jié)
到這,Server也啟動完成了,下面進(jìn)入Service的啟動。