一、核心组件
部分组件简述
组件 | 描述 |
---|---|
ProtocolHandler | 处理请求数据,封装请求,不同的协议不同的处理逻辑 |
Adapter | tomcat流程的入口,处理ProtocolHandler封装的请求 |
Wrapper | tomcat流程的终点,之后会交由用户实现的servlet体系来处理具体业务 |
Valve | tomcat 流程就像工厂的流水线,Value就是流水线的工人,请求就是流水线上的商品,value实现了核心部分的具体处理。像Wrapper,Context,Host,Engine对请求的处理都是通过value来实现 |
Mapper | 根据请求地址和配置找到对应的Wrapper,Context,Host |
部分组件实现简述
组件实现 | 描述 |
---|---|
StandardEngine | Engine的默认实现,创建并使用了StandardEngineValve |
StandardEngineValve | 调用Host中的value,数据流入Host |
StandardHost | Host的默认实现,创建并使用了StandardHostValve |
StandardHostValve | 调用Context中的value,数据流入Context |
StandardContext | Context的默认实现,创建并使用StandardContextValve |
StandardContextValve | 调用wrapper中的value,数据流入Wrapper |
StandardWrapper | Wrapper的默认实现,创建并使StandardWrapperValve来处理servlet |
StandardWrapperValve | 调用servlet体系,数据流入servlet体系 |
CoyoteAdapter | 使用了Mapper。封装请求数据,交给tomcat体系处理。 |
二、源码简述
- org.apache.catalina.core.StandardWrapperValve
final class StandardWrapperValve extends ValveBase {
public final void invoke(Request request, Response response)
throws IOException, ServletException {
//构造servlet,拦截器调用链
ApplicationFilterChain filterChain =
ApplicationFilterFactory.createFilterChain(request, wrapper, servlet);
Container container = this.container;
try {
if ((servlet != null) && (filterChain != null)) {
if (context.getSwallowOutput()) {
try {
SystemLogHandler.startCapture();
if (request.isAsyncDispatching()) {
request.getAsyncContextInternal().doInternalDispatch();
} else {
//调用过滤器链和servlet
filterChain.doFilter(request.getRequest(),
response.getResponse());
}
} finally {
String log = SystemLogHandler.stopCapture();
if (log != null && log.length() > 0) {
context.getLogger().info(log);
}
}
} else {
if (request.isAsyncDispatching()) {
request.getAsyncContextInternal().doInternalDispatch();
} else {
filterChain.doFilter
(request.getRequest(), response.getResponse());
}
}
}
}catch (ClientAbortException | CloseNowException e) {
}
}
}
- org.apache.catalina.core.StandardContextValve
final class StandardContextValve extends ValveBase {
/**
*/
@Override
public final void invoke(Request request, Response response)
throws IOException, ServletException {
//限制这些目录不可直接访问
if ((requestPathMB.startsWithIgnoreCase("/META-INF/", 0))
|| (requestPathMB.equalsIgnoreCase("/META-INF"))
|| (requestPathMB.startsWithIgnoreCase("/WEB-INF/", 0))
|| (requestPathMB.equalsIgnoreCase("/WEB-INF"))) {
response.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
//调用StandardWrapperValue处理servlet相关
wrapper.getPipeline().getFirst().invoke(request, response);
}
}
- org.apache.catalina.core.StandardHostValve
final class StandardHostValve extends ValveBase {
@Override
public final void invoke(Request request, Response response)
throws IOException, ServletException {
try {
if (!response.isErrorReportRequired()) {
//调用Context中的value
context.getPipeline().getFirst().invoke(request, response);
}
} catch (Throwable t) {
}
}
- org.apache.catalina.core.StandardEngineValve
final class StandardEngineValve extends ValveBase {
@Override
public final void invoke(Request request, Response response)
throws IOException, ServletException {
Host host = request.getHost();
if (host == null) {
return;
}
if (request.isAsyncSupported()) {
request.setAsyncSupported(host.getPipeline().isAsyncSupported());
}
//调用Host中的value
host.getPipeline().getFirst().invoke(request, response);
}
}
- org.apache.catalina.connector.CoyoteAdapter
public class CoyoteAdapter implements Adapter {
@Override
public void service(org.apache.coyote.Request req, org.apache.coyote.Response res)
throws Exception {
//调用 StandardEngineValve 处理请求
connector.getService().getContainer().getPipeline().getFirst().invoke(
request, response);
}
//根据请求地址和配置找到对应的Wrapper,Context,Host
protected boolean postParseRequest(org.apache.coyote.Request req, Request request,
org.apache.coyote.Response res, Response response) throws IOException, ServletException {
connector.getService().getMapper().map(serverName, decodedURI,
version, request.getMappingData());
}
}
三、总结
tomcat 处理流程可以分为三部分
- 建立连接,封装处理请求,由ProtocolHandler来完成
- tomcat核心部分,通过Wrapper,Context,Host,Engine 和 value来完成
- 由Wrapper调用servlet体系处理具体业务