Tomcat源码阅读三:过滤器实现

这里省略各种tomcat的初始化和启动过程,简略说下,就是Bootstrap中,初始化HttpConnector类,初始化父容器StandardContext,子容器StandartWapper,以及一些生命周期,然后各种关联赋值,最后调用连接器的初始化方法,然后调用start方法,单一启动模式开启。这里,连接器有serverSocket等待接受请求,同时存在HttpProcess类,和前面一样,线程之间等待,交互,Process得到socet,assign(socket),socket给了处理器,处理器的run方法执行此行  process(socket);处理socket对象,HttpProcessor处理器对象拥有request和response全局变量,在处理器这里,解析了socket之后初始化了request和response对象。然后再处理器的process方法中调用 connector.getContainer().invoke(request, response);父容器启动,一直启动到子容器。这里说下容器关系,父容器是StandadContext,子容器是StandartWapper,它们都继承自ContainerBase类,实现了Context接口,都拥有自己的PipeLine对象,pipeLine对象都拥有自己的处理阀,父容器的基础阀是StandartContextValve,子容器的基础阀是StandardWapperValve等。先说下pipeline的启动,StandartContext继承自ContainerBase类,此类拥有pipeline对象和basic阀和一个Valve阀数组,首先父容器启动,然后调用pipeline的invoke方法,管道启动后,会调用各个阀进行servlet的处理,首先调用Valve数组,若此阀数组为空,则调用basic阀,若basic阀也为空则抛出异常,这里有一个细节就是,Valve阀会按数组下标++顺序执行,执行完后就不在执行Valve阀数组,转而执行basic阀。StandardContext的invoke(   )方法调用super.invoke(request, response);即ContainerBase的invoke()方法,  ContainerBase中的invoke方法调用管道的invoke(  )方法pipeline.invoke(request, response);看下pipeline的启动invok()方法,在管道的invoke方法中初始化了StandardPipeLine的一个内部类  (new StandardPipelineValveContext()).invokeNext(request, response);看下invokeNext方法,内容如下:
         public void invokeNext(Request request, Response response)
            throws IOException, ServletException {

            int subscript = stage;
            stage = stage + 1;

            // Invoke the requested Valve for the current request thread
            if (subscript < valves.length) {
                valves[subscript].invoke(request, response, this);
            } else if ((subscript == valves.length) && (basic != null)) {
                basic.invoke(request, response, this);
            } else {
                throw new ServletException
                    (sm.getString("standardPipeline.noValve"));
            }
        }
注:一个wrapper每次对应一个servlet,wrapper的pipeline每次只会执行一个阀,阀数组下标每次+1
 
     这里的basic阀就是StandardContextValve,在这个阀里面,获取子容器wapper,调用    wrapper.invoke(request, response);在wrapper的invoke里,原理和父容器一样,只不过basic阀是StandardWrapperValve类,在基础阀的invoke( )方法中,调用了容器wrapper的allocate方法  servlet = wrapper.allocate();获取servlet实例,然后执行   ApplicationFilterChain filterChain =
            createFilterChain(request, servlet);这里就到了本文要谈的过滤器的实现。在没有发生异常的前提下,在向请求段发送了ack确认后,就会初始化对象   ApplicationFilterChain filterChain =  createFilterChain(request, servlet);简略说下过滤器的一些实现类,ApplicationFilterChain 代表的是一个过滤器链,FilterDef类代表了一个为web应用定义的过滤器实体,此类并没有太多逻辑方法,只包含一些属性如description描述,displayName和filterClass、filterName,filterClass是过滤器类的全限定名,以及这些属性的get 、set方法。所以说FilterDef并不包含过滤器要实现的逻辑,从某种意义上来说,它只是对开发者展示了一个过滤器定义(包含名字、描述等)。这里还有一个ApplicationFilterConfig类,此类可以理解为过滤器的控制类,包含FilterDef过滤器定义类, ApplicationFilterConfig的getFilter方法返回一个过滤器,方法内部通过类加载器加载FilterDef中的类全限定名。所加载的才是真正的过滤器实现类Filter类。在StandardWrapperValve的invoke( &#x
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值