这幅图是描述servlet原理最常见的一幅图,但是其中却并没有一个Servlet类的存在,这看起来是不是很奇怪呢?
图1.Tomcat容器模型
其实,这幅图本身只是描述的Tomcat容器模型,而这个模型与Servlet的关系又是如何建立的呢。
首先,一个Container包含一个Host,在这个Host中又包含了Servlet容器,而这个Servlet容器中就包含了许多应用,每个应用对应一个Context,自然而然,我们就会联想到每个应用应该包含若干个Servlet的类,但此处为什么包含的是若干个Wrapper呢,那从如下代码就不难理解了
ContextConfig类的webConfig()方法会调用WebXml()的configureContext()方法,通过解析web.xml从而配置Context属性,configureContext()方法包含如下代码:
for (ServletDef servlet : servlets.values()) {
Wrapper wrapper = context.createWrapper();
// Description is ignored
// Display name is ignored
// Icons are ignored
// Only set this if it is non-null else every servlet will get
// marked as the JSP servlet
String jspFile = servlet.getJspFile();
if (jspFile != null) {
wrapper.setJspFile(jspFile);
}
if (servlet.getLoadOnStartup() != null) {
wrapper.setLoadOnStartup(servlet.getLoadOnStartup().intValue());
}
if (servlet.getEnabled() != null) {
wrapper.setEnabled(servlet.getEnabled().booleanValue());
}
wrapper.setName(servlet.getServletName());
Map<String,String> params = servlet.getParameterMap();
for (Entry<String, String> entry : params.entrySet()) {
wrapper.addInitParameter(entry.getKey(), entry.getValue());
}
wrapper.setRunAs(servlet.getRunAs());
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());
}
context.addChild(wrapper);
}