这里省略各种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方法,内容如下:
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"));
}
}
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