我们打开standardService类,查看start方法如下:
public void start() throwsLifecycleException {
// Validate and update our current component state
if (started) {
throw new LifecycleException
(sm.getString("standardService.start.started"));
}
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);
System.out.println
(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 instanceofLifecycle) {
((Lifecycle)container).start();
}
}
}
// Start our defined Connectors second
synchronized (connectors) {
for (int i = 0; i < connectors.length; i++) {
if (connectors[i] instanceofLifecycle)
((Lifecycle)connectors[i]).start();
}
}
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);
}
我们会发现,:
1, 其实这里也采用standardServer的监听者模式,同样的我们去找lifecycleListener的实现类,发现原来在server.xml是没有配置standardService监听器的,所以这里没有监听事件的执行咯
2, 根据代码我们可以知道,接下来会对container属性执行启动,然后再循环执行connectors的启动
3, 我们查看container属性可以知道:
private Container container = null
这里一开始初始化时一个null是无法执行的,但是我们根据属性的get和set方法,那么必定知道有个setContainer方法,如下:
publicvoid setContainer(Container container) {
Container oldContainer =this.container;
if ((oldContainer != null) &&(oldContainer instanceof Engine))
((Engine)oldContainer).setService(null);
this.container = container;
if ((this.container != null) &&(this.container instanceof Engine))
((Engine)this.container).setService(this);
if (started && (this.container!= null) &&
(this.container instanceofLifecycle)) {
try {
((Lifecycle)this.container).start();
} catch (LifecycleException e) {
;
}
}
synchronized (connectors) {
for (int i = 0; i <connectors.length; i++)
connectors[i].setContainer(this.container);
}
if (started && (oldContainer !=null) &&
(oldContainer instanceofLifecycle)) {
try {
((Lifecycle)oldContainer).stop();
} catch (LifecycleException e) {
;
}
}
这里很简单,判断了下container是否是Engine和Lifecycle的实现类,如果是设置了下service和执行了containder的start方法,接下来还循环设置了下connectors里边connector的container这个时候,我们的疑问有来了,既然这里有这个方法,那么究竟是哪个地方调用了该方法呢?
4, 我们再次回想下server.xml文件结构,再次返回到Catalina类Digester设置实例的方法里边:
digester.addRuleSet(newEngineRuleSet("Server/Service/"));
在看看EngineRuleSet中的addRuleInstances方法:
digester.addObjectCreate(prefix +"Engine",
"org.apache.catalina.core.StandardEngine",
"className");
digester.addSetProperties(prefix +"Engine");
digester.addRule(prefix +"Engine",
newLifecycleListenerRule
(digester,
"org.apache.catalina.startup.EngineConfig",
"engineConfigClass"));
digester.addSetNext(prefix +"Engine",
"setContainer",
"org.apache.catalina.Container");
这个时候,我们可以知道这里调用的setContainer,给standardService设置了Container就是StandardEngine.
5,至此StandardService已经将启动操作传递给了standardEngine. 我们看看流程如下:
standardService启动关系类图: