`
goldendoc
  • 浏览: 26355 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Tomcat Wrapper组件

阅读更多

 

Tomcat Wrapper组件

一些基本概念
1、ServletContext:
作用:表示一个web应用的上下文;可以想象成一个Web应用程序的共享数据区域,该区域保存该Web应用程序的共享数据;
生命周期:每个Web应用程序都对应一个ServletContext,保存在Context中,在Context初始化时创建,Context撤销时销毁;
2、servlet-mapping:
作用:按url将请求匹配到servlet;
匹配过程:1) url按最长context path匹配当前Host下的Context;
                   2) 余下的将用于匹配该Context下的Servlet;
匹配规则,顺序如下:
1) 精确匹配:如/user/login;必须以/开头,不能以/*结尾;
2) 通配符匹配:如/customers/*,以最长串优先依次匹配;
3) 扩展名匹配:如/user/register.jsp;任何以*开头,以jsp结尾的mapping都会匹配;
4) 默认匹配:上述3种匹配失败后,将匹配到该mapping上;
3、Filter:
作用:Filter使用户可以改变一个request和修改一个response,它不是一个servlet,也不能产生response,它能够在一个request到达servlet之前预处理request,也可以在response离开servlet时处理response。
类图:如下
其中:
1) FilterDef用于保存从web.xml解析出来的filter定义,包含filterName, filterClass, init-param等;
2) FilterMap用于保存从web.xml解析出来的filter-mapping配置;
3) 当初始化完所有的FilterDef以及FilterMap后,容器会初始化ApplicationFilterConfig,用于Filter内部访问Tomcat容器,如Filter的init-param, ServletContext等;
4) 解析出来的FilterDef、FilterMap以及ApplicationFilterConfig均保存在StandardContext中;
4、Listener:
作用:通过在web.xml中配置<listener>元素,可以在适当的时候收到Tomcat容器的事件通知,从而可以做出相应的响应;
类型:
1) 事件类型:当某事件发生时触发;
a) ServletContextAttributeListener:当ServletContext的属性发生变化(新增、修改、删除)时触发;
b) ServletRequestAttributeListener:当request的属性发生变化(新增、修改、删除)时响应;
c) ServletRequestListener:当请求在经Filter链处理前后时响应;
d) HttpSessionAttributeListener:当session中的属性发生变化(新增、修改、删除)时响应;
2) 生命周期类型:在生命周期中的某个点触发;
a) ServletContextListener:在ServletContext初始化完成和销毁时触发;
b) HttpSessionListener:在session创建和销毁时触发;

重要的数据结构
1、Mapper:
保存Tomcat容器中所有Host, Context, Wrapper及servlet-mapping的映射关系;
2、MappingData:
当前请求经过Mapper后,即决定将该请求交给哪个Host, 哪个Context, 哪个Wrapper来处理;这些数据组成MappingData;

创建ServletContext
1、ServletContext类图

这里采用了门面模式,ApplicationContext仅供tomcat内部使用,在Servlet中取得的servletContext实际上是ApplicationContextFacade的实例,防止外部修改tomcat容器中重要的数据结构;
2、实例化ServletContext
实例化ServletContext是通过StandardContext.getServletContext()方法来完成的:
    public ServletContext getServletContext() {
        if (context == null) {
            context = new ApplicationContext(getBasePath(), this);
            if (altDDName != null)
                context.setAttribute(Globals.ALT_DD_ATTR,altDDName);
        }
        return (context.getFacade());
    }

解析部署描述符web.xml
1、初始化Wrapper
当StandardContext初始化时,会解析web.xml文件(参考WebRuleSet);当解析到web-app/servlet标签时会调用StandardContext.createWrapper()方法,从而构造Wrapper组件,并将其作为子节点添加到当前Context下;
初始化Wrapper后,会设置与该servlet相关的配置,如servlet-name, servlet-class, init-param, jsp-file, load-on-startup等;这些配置值都是刚才构建出来的Wrapper组件的属性;
2、初始化servlet-mapping
由于servlet-mapping是针对Context的,处理servlet-mapping的工作由Context来完成,主要工作如下:
1) 根据servert-name找到该Context的子节点Wrapper,然后将该mapping添加到Wrapper中;
2) 将该Wrapper添加到当前Context的Mapper中,供ServletContext使用;
3、初始化filter及filter-mapping
1) 解析filter:调用StandardContext.addFilterDef(FilterDef filterDef),如下:
    public void addFilterDef(FilterDef filterDef) {
        synchronized (filterDefs) {
            filterDefs.put(filterDef.getFilterName(), filterDef);
        }
        fireContainerEvent("addFilterDef", filterDef);
    }
即:将filterDef以filterName为key保存在Map中;
2) 解析filter-mapping:调用StandardContext.addFilterMap(FilterMap filterMap),如下:
    public void addFilterMap(FilterMap filterMap) {
        // 先会做一些校验
        synchronized (filterMaps) {
            FilterMap results[] =new FilterMap[filterMaps.length + 1];
            System.arraycopy(filterMaps, 0, results, 0, filterMaps.length);
            results[filterMaps.length] = filterMap;
            filterMaps = results;
        }
        fireContainerEvent("addFilterMap", filterMap);
    }
3) 初始化ApplicationFilterConfig:当StandardContext启动时,会通过filterStart()方法来初始化ApplicationFilterConfig:将1)中保存的每个filterDef和当前StandardContext包装成一个ApplicationFilterConfig,供后面的创建filter链时使用;
4、初始化listener
当解析到web.xml中的<listener>元素时,会调用Standard.addApplicationListener(String listener)将listener的class信息保存起来,然后在StandardContext启动时,通过listenerStart()方法来初始化listener:实例化先前保存起来的listener,并按事件/生命周期分类保存其实例;
此时StandardContext初始化也快完成了,因此会触发ServletContextListener.contextInitialized()方法;

Servlet的loadOnStartup
在配置Servlet时,可以指定其loadOnStartup属性,该属性值决定了Servlet在容器启动后是否加载及加载顺序,默认为-1,表示不加载;
StandardContext在加载完所有Servlet配置后,会检查当前Context下的所有Wrapper的loadOnStartup属性值,当值大于0时,通过TreeMap按loadOnStartup从小到大排序后,分别调用每个Wrapper.load()方法来完成Servlet的初始化:
1) 根据servletClass是否是Tomcat内部servlet,决定是用webappClassloader还是用serverClassloader来装载servletClass;
2) 实例化servletClass;
3) 如果servlet是单线程(即一个servlet实例同时只能处理一个请求),则初始化一个servlet pool,用于存放空闲的servlet实例;后面在处理请求时分配servlet则会用到该servlet pool;

Mapper相关
1、先看看Mapper相关的类图

请不要把上图中的Host, Context, Wrapper和Tomcat中的Host组件、Context组件、Wrapper组件相混淆了,它们仅仅代表这三个组件的映射关系,真正所对应的组件实例引用存放在MapperElement抽象类中的object属性上;
2、初始化Mapper结构
我们再来回顾一下Tomcat容器的初始化过程:
1) 解析server.xml(由Catalina类来完成),同时调用StandardServer.start()方法来初始化Server组件;
2) Server组件初始化时,调用StandardService.start()方法来初始化Service组件;
3) 在StandardService.start()中,先完成所有内嵌组件的初始化(Engine, Host, Context, Wrapper等),然后调用Connect.start()方法来初始化Connector组件;
4) 由于在Connector初始化时,所有的内嵌组件都已初始化完毕,此时便可以完成Mapper的构造了;
初始化Mapper主要是由MapperListener来完成(在Connector.start()中调用MapperListener.init()方法):
1) 注册Engine:找到defaultHost,并设置Mapper的defaultHostName属性;
2) 注册所有的Host:针对每个Host组件,都构造一个Mapper$Host实例,name属性为该Host组件的name,object属性即该Host组件;另外,针对Host组件的别名,也会产生新的Mapper$Host实例,不过其object和Mapper$contextList的引用相同;
3) 注册所有的Context:针对每个Context组件,根据其hostName,将其加到对应Mapper$Host实例的Mapper$contextList中去;
4) 注册所有的Wrapper:和注册Context类似,将每个Wrapper组件根据其servlet-mapping保存到Mapper$Context的相应属性上;
3、MappingData的构造
当请求到达后,在交给Engine处理前,会构造MappingData(见CoyoteAdapter.postParseRequest()方法):
1) 根据请求的host属性,从Mapper中找到相应的Host组件及Mapper$Context数组;此时如果没有指定host属性的Host组件,则取defaultHostName所对应的Host组件;
2) 根据请求的uri,找到Context组件;
3) 根据请求的uri,按servlet-mapping规则,依次查找,直接找到对应的Wrapper组件;此时如果找不到,则依次查找welcomeFile所对应Wrapper组件;
4) 如果最后还是没有找到,则返回defaultWrapper组件;
5) 将匹配到的Host, Context, Wrapper保存在request中;

Wrapper组件对请求的处理
当MappingData构造完成后,CoyoteAdapter便将请求交给Engine、Host、Context、Wrapper组件进行处理;在Context组件中,StandardContextValve直接从request中取出Wrapper,然后交给它处理;下面看看Wrapper组件是如何处理的?
1、StandardWrapperValve
Wrapper组件对请求的处理,是通过StandardWrapperValve来完成的:
1) 从Wrapper中分配一个servlet实例;
2) 根据当前servlet和requestPath将匹配到的filter加到filter链中;
3) 调用filter chain处理请求和响应;当所有filter执行完,最后才执行servlet.service()方法;
3
1
分享到:
评论
1 楼 xiaoZ5919 2011-11-14  
好文章!thanks for sharing

相关推荐

    tomcat组件启动时序图.vsdx

    对于tomcat的启动流程分析,从主流程Bootstrap -&gt; Catalina -&gt; Server -&gt; service -&gt; engine,connector;和分流程1.engine-&gt;host-&gt;context-&gt;wrapper ;2.connector -&gt; ProtocolHandler-&gt;Endpoint;之中的方法调用进行...

    tomcat 架构 分析

    了解Tomcat的架构,从Connector和Container这两个核心组件开始,理解它们的协同工作方式,以及Tomcat如何通过模块化的设计来管理服务组件的生命周期,对于深入使用和定制Tomcat是非常重要的。同时,观察和学习Tomcat...

    tomcat源码研读笔记中的tomcat源码

    - **Servlet调用**: Wrapper组件负责调用Servlet的service方法,执行实际的业务逻辑。 - **响应生成**: Servlet生成响应内容,通过Wrapper、Container和Connector返回给客户端。 4. **部署与配置** - **web.xml*...

    tomcat的工作原理

    Tomcat的工作原理涉及到多个组件,包括连接器(Connectors)、容器(Containers)、管道(Pipelines)与阀门(Valves),以及生命周期管理机制等。本文将详细探讨这些关键组成部分,揭示Tomcat如何高效地处理HTTP...

    Tomcat培训学习资料

    此外,Tomcat的组件具有一个共同的特性,即它们都遵循“Lifecycle”组件生命周期,从而实现组件的启动、停止等功能。 在Tomcat的配置和优化方面,需要了解其配置文件的细节,如server.xml、web.xml、context.xml等...

    tomcat8源码

    - **Container**:Tomcat中的每个组件都是一个Container,负责处理请求并生成响应。最顶层的Container是Engine,接着是Host(主机),然后是Context(应用上下文),最后是Wrapper(Servlet容器)。 3. **生命周期...

    tomcat7源代码

    3. **Jasper**:Jasper是Tomcat处理JSP的组件,它将JSP文件转换为Java源代码,再编译成字节码执行。Jasper的工作流程包括预编译、编译、加载和执行四个阶段,对于理解JSP的生命周期和执行过程具有重要意义。 4. **...

    tomcat源码 tomcat本来就是开源的

    #### 五、Tomcat核心组件介绍 - **Connector**:负责接收客户端请求并将其转发给容器处理。支持HTTP/HTTPS协议,可以通过配置文件灵活调整其工作参数。 - **Container**:用于装载和管理Servlet,提供生命周期管理...

    tomcat是如何工作的

    Connector组件是Tomcat的核心之一,主要负责接收来自客户端的请求并将这些请求转发给相应的Container进行处理。它支持多种协议,包括HTTP/1.1、AJP/1.3等。当一个请求到达时,Connector会创建一个新的线程来处理这个...

    Tomcat架构解析文档.zip

    - 对所有Tomcat组件提供生命周期管理,包括初始化、启动、停止和销毁等阶段。 6. **Pipeline和Valve组件** - **Pipeline** 类似于管道,Valve则相当于管道中的阀门,每个Valve执行特定的任务。请求和响应在...

    TOMCAT源码分析(启动框架)

    它包含了Engine、Host、Context和Wrapper等层次结构,这些组件共同构成了Tomcat的请求处理机制。 - Engine:Engine是最高级别的容器,处理所有传入的请求。默认情况下,每个Tomcat实例只有一个Engine。 - Host...

    HOw Tomcat Works

    4. **Servlet执行**:Wrapper组件调用Servlet的`service()`方法,执行请求处理逻辑。 5. **响应构建**:Servlet生成的响应内容被包装成HTTP响应,返回给客户端。 三、Tomcat配置与优化 1. **server.xml配置**:这...

    《深入剖析 Tomcat》PDF版本下载.txt

    - **Connector**:它是Tomcat的核心组件之一,负责接收客户端请求并将请求传递给合适的Container进行处理。Connector支持多种协议,如HTTP/1.1、AJP/1.3等。通过配置不同的Connector,可以实现Tomcat同时支持多种...

    Tomcat 架构 原理

    它包含了Engine、Host、Context和Wrapper组件的具体实现。 4. **Jasper(JSP编译器)** Jasper是Tomcat中的JSP引擎,负责将JSP页面转换为Servlet类,从而提高JSP的执行效率。 三、Tomcat启动流程 当Tomcat启动时...

    传智Tomcat(全)下载地址

    Tomcat主要由以下组件构成: 1. **Connector**:负责监听客户端请求,将请求分发给容器。 2. **Container**:处理具体的Web应用程序。包括Engine、Host、Context和Wrapper等层次结构。 3. **Catalina**:核心容器...

    how tomcat work

    Tomcat的核心组件包括Catalina(核心引擎)、 Coyote(HTTP/1.1协议处理器)和Jasper(JSP编译器)。Catalina负责管理Servlet容器,Coyote处理网络通信,Jasper则将JSP转换为Servlet并编译执行。 2. **启动过程**...

    how tomcat works

    为了执行以上任务,Tomcat内部使用了许多组件。例如: - **管理模块**:用于处理用户会话等管理功能。 - **加载器**:负责加载servlet类。 - **连接器**:连接器内部又包括多个子组件,用于处理HTTP请求和响应。 - *...

    tomcat-catalina-7.0.27.jar.zip

    Catalina是Tomcat的核心组件,负责处理Servlet和JSP的请求,而`tomcat-catalina-7.0.27.jar`则是Catalina模块在Tomcat 7.0.27版本中的实现文件。 1. **Catalina架构** Catalina遵循Java Servlet规范,提供了一个...

    tomcat架构

    所有Tomcat组件都遵循这一生命周期,使得整个服务器可以在启动时初始化所有组件,并在关闭时停止所有正在运行的组件。 4. 服务(Service):服务是一个或多个连接器和一个容器的组合,它将特定的连接器和容器绑定在...

Global site tag (gtag.js) - Google Analytics