servlet原理--Tomcat与Servlet如何解耦

来源:互联网 发布:数据库运维管理制度 编辑:程序博客网 时间:2024/05/02 02:10

这幅图是描述servlet原理最常见的一幅图,但是其中却并没有一个Servlet类的存在,这看起来是不是很奇怪呢?

图1.Tomcat容器模型

图 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);        }

从以上代码不难看到,通过遍历Map<ServletDef>来逐个生成(它实际是通过web.xml解析得到的对象,该对象包含了每个servlet的配置信息,包括servlet名称url、对应的类名等等)Wrapper对象,这一过程实际是通过Wrapper实现了对Servlet的再封装,这样Wrapper是Tomcat容器的一部分,而非Servlet本身,从而避免了Tomcat与Servlet的强耦合。


0 0
原创粉丝点击