两者皆共有HttpServletRequest接口,实现HttpServletRequest接口方法。Request类是tomcat定义的,实例方法中有些是关于tomcat内部的方法。而RequestFacade类,是对org.apache.catalina.connector Request类的一种封装,提供了一些经常使用的方法,封装的tomcat内部的方法。因此RequestFacade是对外暴露的对象是connector/Request类getRequest()方法中new RequestFacade(this)方法得到。
1.RequestFacade类
通过单参构造,初始化类属性 request。并实现了HttpServletRequest接口的方法。
public class RequestFacade implements HttpServletRequest {
protected Request request = null;
public RequestFacade(Request request) {
this.request = request;
}
...
}
2.package org.apache.catalina.connector Request类
该类有单参构造方法Request(Connector connector),初始化属性成员。 有个属性,org.apache.coyote.Request coyoteRequest。这是服务器请求的底层对象。看源码可得:RequestFacade->org.apache.catalina.connector Request->org.apache.coyote.Request coyoteRequest->this.coyoteRequest.getXXX。
Http11Processor类,继承抽象类 AbstractProcessor。参构造方法初始化属性Adapter adapter ,org.apache.coyote Request request。该adapter的值是项目启动时,自动注入的一个CoyoteAdapter型实例(适配器)。该适配器的service(Request req, Response res)传入的时org.apache.coyote.Request包new的对象coyoteRequest,接着adapter中connector创建org.apache.catalina.connector Request对象request,之后调用request.setCoyoteRequest(coyoteRequest),最后由StandardEngineValve.invoke方法,将org.apache.catalina.connector Request对象request传到下一层。
3.抽象类 RequestContextHolder
该类作用,在发起请求的线程中通过该类的静态方法RequestFacade实例对象。原理通过ThreadLocal<RequestAttributes>实现的。1. StandardWrapperValve类中,invoke()中ApplicationFilterFactory.createFilterChain()得到请求中的过滤链filterChain(ApplicationFilterChain),filterChain[2]为ApplicationFilterConfig对象的属性filter(Filter)为OrderedRequestContextFilter类(父类RequestContextFilter父类OncePerRequestFilter)。2.当执行到OrderedRequestContextFilter时,其实执行父类RequestContextFilter的doFilterInternal()方法中RequestContextHolder.setRequestAttribute(requestAttributes,false),接着执行下一个过滤器。
4.OncePerRequestFilter类
继承该类的过滤器在一次请求中只执行一次。原理在OncePerRequestFilter中doFilter方法将首次经过该过滤器时,会判断request对象的attribute(ConcurrentHashMap)中有对应的过滤器名字,如果有,就执行下一个过滤器;如果没有,会将key为className + ".FILTERED",value为true,放在attribute中,执行子类的doFilterInternal()方法执行逻辑。
5.AdviceFilter过滤器
doFilterInternal()方法中,1.boolean continueChain = preHandle(request, response)。2.
executeChain(request, response, chain)。3.postHandle(request, response);
总结。应用过滤器时,只执行一次的情况下,可以选择继承OncePerRequestFilter实现过滤器。在一些场景下,需要得到request的对象,可以通过RequestContextHolder.getRequestAttribute()。对于RequestFacade涉及到门面设计模式,如果一个类的接口过多,我们只需要使用一部分。这样可以使用Facade模式,创建新的facade对象,封装原来的对象,只暴露facade对象。