路由表的建立->路由的匹配->Servlet的执行
//路由表的建立---------------1
class org.apache.catalina.core.StandardService{
protected void startInternal() throws LifecycleException {
// org.apache.catalina.core.StandardEngine
// org.apache.catalina.core.StandardHost
// org.apache.catalina.core.StandardContext --- context
// org.apache.catalina.core.StandardWrapper --- context.addChild(wrapper);
// org.apache.tomcat.util.descriptor.web.SessionConfig --- context.getServletContext().getSessionCookieConfig().setXXX(...);
// org.apache.tomcat.util.descriptor.web.FilterDef --- context.addFilterDef(filter);
// org.apache.tomcat.util.descriptor.web.FilterMap --- context.addFilterMap(filterMap);
// <listener-class>cn.java.listener.HelloListener</listener-class> --- context.addApplicationListener(listener);
engine.start(); // 查找主机、上下文,构造对象树
// 路由表的建立
//!!! 查找默认虚拟主机/让 mapperListener 成为StandardEngine、StandardHost、StandardContext的监听器/注册路径信息到mapper中
mapperListener.start();
}
}
// StandardContext的事件监听器,用来解析上下文
class org.apache.catalina.startup.ContextConfig{
private void configureContext(WebXml webxml) {
// context === org.apache.catalina.core.StandardContext
for (FilterDef filter : webxml.getFilters().values()) { // 过滤器
if (filter.getAsyncSupported() == null) {
filter.setAsyncSupported("false");
}
context.addFilterDef(filter);
}
for (FilterMap filterMap : webxml.getFilterMappings()) { // 过滤器映射
context.addFilterMap(filterMap);
}
for (String listener : webxml.getListeners()) { // 应用监听器
context.addApplicationListener(listener);
}
for (ServletDef servlet : webxml.getServlets().values()) { // 添加Servlet对象
// org.apache.catalina.core.StandardContext.createWrapper();
// 创建org.apache.catalina.core.StandardWrapper对象
// 给wrapper添加生命周期监听器
// 给wrapper添加容器监听器
Wrapper wrapper = context.createWrapper();
// Description is ignored
// Display name is ignored
// Icons are ignored
// jsp-file gets passed to the JSP Servlet as an init-param
if (servlet.getLoadOnStartup() != null) {
wrapper.setLoadOnStartup(servlet.getLoadOnStartup().intValue());
}
if (servlet.getEnabled() != null) {
wrapper.setEnabled(servlet.getEnabled().booleanValue());
}
wrapper.setName(servlet.getServletName()); // servlet的名称
Map<String,String> params = servlet.getParameterMap(); // Servlet的属性
for (Entry<String, String> entry : params.entrySet()) {
wrapper.addInitParameter(entry.getKey(), entry.getValue());
}
wrapper.setRunAs(servlet.getRunAs());
Set<SecurityRoleRef> roleRefs = servlet.getSecurityRoleRefs();
for (SecurityRoleRef roleRef : roleRefs) {
wrapper.addSecurityReference(
roleRef.getName(), roleRef.getLink());
}
wrapper.setServletClass(servlet.getServletClass()); // Servlet的类名
MultipartDef multipartdef = servlet.getMultipartDef();
if (multipartdef != null) {
if (multipartdef.getMaxFileSize() != null &&
multipartdef.getMaxRequestSize()!= null &&
multipartdef.getFileSizeThreshold() != null) {
wrapper.setMultipartConfigElement(new MultipartConfigElement(
multipartdef.getLocation(),
Long.parseLong(multipartdef.getMaxFileSize()),
Long.parseLong(multipartdef.getMaxRequestSize()),
Integer.parseInt(
multipartdef.getFileSizeThreshold())));
} else {
wrapper.setMultipartConfigElement(new MultipartConfigElement(
multipartdef.getLocation()));
}
}
if (servlet.getAsyncSupported() != null) {
wrapper.setAsyncSupported(
servlet.getAsyncSupported().booleanValue());
}
wrapper.setOverridable(servlet.isOverridable());
// wrapper === org.apache.catalina.core.StandardWrapper
context.addChild(wrapper);
}
for (Entry<String, String> entry :
webxml.getServletMappings().entrySet()) { // 添加Servlet映射
context.addServletMapping(entry.getKey(), entry.getValue());
}
SessionConfig sessionConfig = webxml.getSessionConfig();
if (sessionConfig != null) { // session配置
if (sessionConfig.getSessionTimeout() != null) {
context.setSessionTimeout(
sessionConfig.getSessionTimeout().intValue());
}
SessionCookieConfig scc =
context.getServletContext().getSessionCookieConfig();//!!!
scc.setName(sessionConfig.getCookieName());
scc.setDomain(sessionConfig.getCookieDomain());
scc.setPath(sessionConfig.getCookiePath());
scc.setComment(sessionConfig.getCookieComment());
if (sessionConfig.getCookieHttpOnly() != null) {
scc.setHttpOnly(sessionConfig.getCookieHttpOnly().booleanValue());
}
if (sessionConfig.getCookieSecure() != null) {
scc.setSecure(sessionConfig.getCookieSecure().booleanValue());
}
if (sessionConfig.getCookieMaxAge() != null) {
scc.setMaxAge(sessionConfig.getCookieMaxAge().intValue());
}
if (sessionConfig.getSessionTrackingModes().size() > 0) {
context.getServletContext().setSessionTrackingModes(
sessionConfig.getSessionTrackingModes());
}
}
}
}
class org.apache.catalina.mapper.MapperListener{
// 路由表的建立
public void startInternal() throws LifecycleException {
setState(LifecycleState.STARTING);
Engine engine = service.getContainer(); // org.apache.catalina.core.StandardEngine
if (engine == null) {
return;
}
findDefaultHost(); // 查找默认虚拟主机
addListeners(engine);// 让自己成为StandardEngine、StandardHost、StandardContext的监听器
Container[] conHosts = engine.findChildren(); // 注册路径信息到mapper中
for (Container conHost : conHosts) { //
Host host = (Host) conHost; // org.apache.catalina.core.StandardHost
if (!LifecycleState.NEW.equals(host.getState())) {
// Registering the host will register the context and wrappers
registerHost(host);
}
}
}
// 添加虚拟主机
private void registerHost(Host host) {
String[] aliases = host.findAliases(); // org.apache.catalina.core.StandardHost
mapper.addHost(host.getName(), aliases, host); // mapper.hosts
for (Container container : host.findChildren()) {
if (container.getState().isAvailable()) { // org.apache.catalina.core.StandardContext
registerContext((Context) container);
}
}
}
// 添加上下文
private void registerContext(Context context) {
String contextPath = context.getPath();
if ("/".equals(contextPath)) {
contextPath = "";
}
Host host = (Host)context.getParent(); // org.apache.catalina.core.StandardHost
WebResourceRoot resources = context.getResources();
String[] welcomeFiles = context.findWelcomeFiles();
List<WrapperMappingInfo> wrappers = new ArrayList<>();
for (Container container : context.findChildren()) { // org.apache.catalina.core.StandardWrapper列表
prepareWrapperMappingInfo(context, (Wrapper) container, wrappers);
}
// 添加到map
mapper.addContextVersion(host.getName(), host, contextPath,
context.getWebappVersion(), context, welcomeFiles, resources,
wrappers);
}
private void prepareWrapperMappingInfo(Context context, Wrapper wrapper,
List<WrapperMappingInfo> wrappers) {
String wrapperName = wrapper.getName();// Servlet名称<servlet-name></servlet-name>
boolean resourceOnly = context.isResourceOnlyServlet(wrapperName);
String[] mappings = wrapper.findMappings();
for (String mapping : mappings) {
boolean jspWildCard = (wrapperName.equals("jsp")
&& mapping.endsWith("/*"));
wrappers.add(new WrapperMappingInfo(mapping, wrapper, jspWildCard,
resourceOnly));
}
}
}
// 路由表的映射---------------2
class org.apache.catalina.connector.CoyoteAdapter{
public void service(org.apache.coyote.Request req,
org.apache.coyote.Response res)
throws Exception {
postParseSuccess = postParseRequest(req, request, res, response);//!!!! 解析scheme、查找路由、sessionID
// request.getMappingData() 内部存储路由映射对象和StandardWrapper对象(StandardWrapper是Servlet的包装器)
}
// 解析请求
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()); // 映射出路由 -------------------并创建出相应对象!!!!
}
}
// 路由映射
class org.apache.catalina.mapper.Mapper{
public void map(MessageBytes host, MessageBytes uri, String version,
MappingData mappingData) throws IOException {
internalMap(host.getCharChunk(), uri.getCharChunk(), version,
mappingData);
}
// 查找虚拟主机的映射,设置到mappingData.host
// 查找上下文路径的映射,设置到mappingData.contextPath
// 查找上下文的映射,设置到mappingData.context
// 查找Servlet的映射,设置到mappingData.wrapper
private final void internalMap(CharChunk host, CharChunk uri,
String version, MappingData mappingData) throws IOException {
// Virtual host mapping 查找主机映射
MappedHost[] hosts = this.hosts;
MappedHost mappedHost = exactFindIgnoreCase(hosts, host);
mappingData.host = mappedHost.object;
// Context mapping 上下文映射
ContextList contextList = mappedHost.contextList; // 虚拟主机的目录列表
MappedContext[] contexts = contextList.contexts;
// ...
mappingData.contextPath.setString(context.name); // 上下文地址
ContextVersion contextVersion = null;
ContextVersion[] contextVersions = context.versions; // 上下文版本列表
mappingData.context = contextVersion.object;
mappingData.contextSlashCount = contextVersion.slashCount;
// Wrapper mapping Servlet的映射
if (!contextVersion.isPaused()) {
internalMapWrapper(contextVersion, uri, mappingData);
}
}
// 查找Servlet的映射,设置到mappingData.wrapper
private final void internalMapWrapper(ContextVersion contextVersion,
CharChunk path,
MappingData mappingData) throws IOException {
// Rule 1 -- Exact Match Servlet的匹配
MappedWrapper[] exactWrappers = contextVersion.exactWrappers;
internalMapExactWrapper(exactWrappers, path, mappingData);
if (mappingData.wrapper == null) {
//....
}
// ....
}
}
// Servlet的执行---------------3
class org.apache.catalina.connector.CoyoteAdapter{
public void service(org.apache.coyote.Request req,
org.apache.coyote.Response res)
throws Exception {
// 执行管道链条
// org.apache.catalina.core.StandardService --- getService()
// org.apache.catalina.core.StandardEngine --- getContainer()
// org.apache.catalina.core.StandardPipeline --- getPipeline()
// org.apache.catalina.core.StandardEngineValve --- getFirst()
connector.getService().getContainer().getPipeline().getFirst().invoke(request, response);
request.finishRequest();
response.finishResponse(); // 输出数据,并关闭输出流
}
}
class org.apache.catalina.core.StandardEngineValve{
public final void invoke(Request request, Response response)
throws IOException, ServletException {
// org.apache.catalina.core.StandardHostValve
host.getPipeline().getFirst().invoke(request, response);
}
}
class org.apache.catalina.core.StandardHostValve{
public final void invoke(Request request, Response response)
throws IOException, ServletException {
// org.apache.catalina.core.StandardContextValve
context.getPipeline().getFirst().invoke(request, response); //!!!!
response.setSuspended(false);
}
}
class org.apache.catalina.core.StandardContextValve{
// request === org.apache.catalina.connector.Request
Wrapper wrapper = request.getWrapper(); // Servlet对象
// 执行Servlet请求 !!!! wrapper === org.apache.catalina.core.StandardWrapper
// org.apache.catalina.core.StandardWrapperValve.invoke(request, response);
wrapper.getPipeline().getFirst().invoke(request, response);
}
//
class org.apache.catalina.connector.Request{
public Wrapper getWrapper() {
return mappingData.wrapper;
}
public MappingData getMappingData() {
return mappingData;
}
}