Tomcat 中的 Engine
Engine 定义
public interface Engine extends Container {
public String getDefaultHost();
public void setDefaultHost(String defaultHost);
public String getJvmRoute();
public void setJvmRoute(String jvmRouteId);
public Service getService();
public void setService(Service service);
}
从定义中可以看出
- Engine 继承了 container 接口。注意 Container 接口继承了 Lifecycle 接口
- Engine 的实现类是 StandardEngine
StandardEngine 的构造方法
public StandardEngine() {
super();
//这里为 pipeline 设置了一个基础阀 StandardEngineValve
pipeline.setBasic(new StandardEngineValve());
/* Set the jmvRoute using the system property jvmRoute */
try {
setJvmRoute(System.getProperty("jvmRoute"));
} catch(Exception ex) {
log.warn(sm.getString("standardEngine.jvmRouteFail"));
}
// By default, the engine will hold the reloading thread
backgroundProcessorDelay = 10;
}
- 这里需要补充一点 容器对象的创建是在 Catalina 的 load 方法中通过 Digester 对象的 parse 方法解析xml文件时创建的,后面的添加子容器也是在 Digester 对象解析xml文件时完成的
StandardEngine 的 initInternal 方法
protected void initInternal() throws LifecycleException {
// Ensure that a Realm is present before any attempt is made to start
// one. This will create the default NullRealm if necessary.
//注意这里并没有初始化Host、Context、Wrapper等
getRealm();
//在父类中创建了一个 startStopExecutor 的线程池
super.initInternal();
}
- 这里需要注意的是,初始化init过程到这就结束了。后面的Host、Context、Wrapper的初始化是在start中进行的
StandardEngine 的 startInternal 方法
protected synchronized void startInternal() throws LifecycleException {
// Log our server identification information
if(log.isInfoEnabled())
log.info( "Starting Servlet Engine: " + ServerInfo.getServerInfo());
// Standard container startup
//调用父类的方法,去看看父类ContainerBase的 startInternal 方法做了什么
super.startInternal();
}
ContainerBase的 startInternal 方法
protected synchronized void startInternal() throws LifecycleException {
//这里是分层调用 每个容器都会来这里寻找子容器然后调用 start 方法
//直到找到最后的 Wrapper 才结束
// Start our subordinate components, if any
logger = null;
getLogger();
Cluster cluster = getClusterInternal();
if (cluster instanceof Lifecycle) {
((Lifecycle) cluster).start();
}
Realm realm = getRealmInternal();
if (realm instanceof Lifecycle) {
((Lifecycle) realm).start();
}
// Start our child containers, if any
//重点在这,启动子容器
Container children[] = findChildren();
List<Future<Void>> results = new ArrayList<>();
for (int i = 0; i < children.length; i++) {
//这里直接跳转到 org.apache.catalina.core.ContainerBase.StartChild 的 call 方法
//这里要注意看 StartChild 的 call 方法,这个 call 方法中会调用 children 的 start 方法
//注意这里的 children 是 LifeCycle 的实现类,所以会进入LifeCycleBase 的start 方法
results.add(startStopExecutor.submit(new StartChild(children[i])));
}
MultiThrowable multiThrowable = null;
//这里表示等待所有子容器全部启动再执行后面的操作
for (Future<Void> result : results) {
try {
result.get();
} catch (Throwable e) {
log.error(sm.getString("containerBase.threadedStartFailed"), e);
if (multiThrowable == null) {
multiThrowable = new MultiThrowable();
}
multiThrowable.add(e);
}
}
if (multiThrowable != null) {
throw new LifecycleException(sm.getString("containerBase.threadedStartFailed"),
multiThrowable.getThrowable());
}
// Start the Valves in our pipeline (including the basic), if any
//启动 pipeline
if (pipeline instanceof Lifecycle) {
((Lifecycle) pipeline).start();
}
//这里会激发监听器HostConfig
//进入 HostConfig 的 start 方法
setState(LifecycleState.STARTING);
// Start our thread
threadStart();
}
再看 LifecycleBase 的 start 方法
public final synchronized void start() throws LifecycleException {
if (LifecycleState.STARTING_PREP.equals(state) || LifecycleState.STARTING.equals(state) ||
LifecycleState.STARTED.equals(state)) {
if (log.isDebugEnabled()) {
Exception e = new LifecycleException();
log.debug(sm.getString("lifecycleBase.alreadyStarted", toString()), e);
} else if (log.isInfoEnabled()) {
log.info(sm.getString("lifecycleBase.alreadyStarted", toString()));
}
return;
}
if (state.equals(LifecycleState.NEW)) {
//注意如果没有初始化,会先进入这里初始化以后再执行下面的start方法
init();
} else if (state.equals(LifecycleState.FAILED)) {
stop();
} else if (!state.equals(LifecycleState.INITIALIZED) &&
!state.equals(LifecycleState.STOPPED)) {
invalidTransition(Lifecycle.BEFORE_START_EVENT);
}
try {
setStateInternal(LifecycleState.STARTING_PREP, null, false);
//子类实现,跟 init 一样
startInternal();
if (state.equals(LifecycleState.FAILED)) {
// This is a 'controlled' failure. The component put itself into the
// FAILED state so call stop() to complete the clean-up.
stop();
} else if (!state.equals(LifecycleState.STARTING)) {
// Shouldn't be necessary but acts as a check that sub-classes are
// doing what they are supposed to.
invalidTransition(Lifecycle.AFTER_START_EVENT);
} else {
setStateInternal(LifecycleState.STARTED, null, false);
}
} catch (Throwable t) {
// This is an 'uncontrolled' failure so put the component into the
// FAILED state and throw an exception.
handleSubClassException(t, "lifecycleBase.startFail", toString());
}
}
- 这里要注意的是,如果没有初始化,会在这里先执行初始化再start
- 在StandardEngine 的start方法中,会初始化所有的子容器,并执行所有子容器的start方法
- 默认只有一个子容器 Host
StandardEngine 的 基础阀 -- StandardEngineValve
public final void invoke(Request request, Response response)
throws IOException, ServletException {
// Select the Host to be used for this Request
//从 request 中获取 Host 对象
Host host = request.getHost();
if (host == null) {
response.sendError
(HttpServletResponse.SC_BAD_REQUEST,
sm.getString("standardEngine.noHost",
request.getServerName()));
return;
}
if (request.isAsyncSupported()) {
request.setAsyncSupported(host.getPipeline().isAsyncSupported());
}
// Ask this Host to process this request
//调用 Host 对象Pipeline 中的 Valve
host.getPipeline().getFirst().invoke(request, response);
}
- 这里只关注 invoke 方法
- StandardEngineValve 中直接从 request 对象获取了 Host 对象然后调用 Host 对象的 Pipeline
小结
- 这里能看到第一篇 tomcat 源码分析最后的流程图是错误的。Host、Context、Wrapper的 init 并不是在 Engine 的 init 中调用的,而是在 Engine 的start 方法中调用的