零、引言

RequetContextListener从名字结尾Listener来看就知道属于监听器。

所谓监听器就是监听某种动作,在其开始(初始化)和结束(销毁)的时候进行某些操作。

由此可以猜测:该类用于在RequetContext(请求上下文对象)创建和销毁的时候进行某些操作(哪些操作?结尾总结!)

一、web.xml配置

要使用该listener对象需要在web.xml中进行如下配置。

<!-- 此监听器是监听HttpRequest对象,方便ContextHolderUtils程序调用HttpRequest对象 --><listener><description>request监听器</description><listener-class>org.springframework.web.context.request.RequestContextListener</listener-class></listener>

 

二、三个重要类解读

2.1 RequetContextListener

seo优化培训,网络推广培训,网络营销培训,SEM培训,网络优化,在线营销培训

public class RequestContextListener implements ServletRequestListener {    private static final String REQUEST_ATTRIBUTES_ATTRIBUTE =
            RequestContextListener.class.getName() + ".REQUEST_ATTRIBUTES";    // 在请求进入的时候,初始化变量放入ThreadLocal<T>中    @Override    public void requestInitialized(ServletRequestEvent requestEvent) {        //判定当前的requetEvent中获取的ServletRequest()对象是否是HttpServletRequet对象
        if (!(requestEvent.getServletRequest() instanceof HttpServletRequest)) {            throw new IllegalArgumentException(                    "Request is not an HttpServletRequest: " + requestEvent.getServletRequest());
        }        //强制转型为 HttpServletRequest
        HttpServletRequest request = (HttpServletRequest) requestEvent.getServletRequest();        // ServletRequestAttributes 保存了HttpServletRequet、Response、Session等变量
        ServletRequestAttributes attributes = new ServletRequestAttributes(request);
        request.setAttribute(REQUEST_ATTRIBUTES_ATTRIBUTE, attributes);
        LocaleContextHolder.setLocale(request.getLocale());        //RequestContextHolder里面有一个ThreadLocal,当前线程共享        RequestContextHolder.setRequestAttributes(attributes);
    }    //在请求被销毁的时候,将在初始化时候的ThreadLocal变量清空。    @Override    public void requestDestroyed(ServletRequestEvent requestEvent) {
        ...
    }
}

seo优化培训,网络推广培训,网络营销培训,SEM培训,网络优化,在线营销培训

 

 2.2 RequetContextHolder

seo优化培训,网络推广培训,网络营销培训,SEM培训,网络优化,在线营销培训

public abstract class RequestContextHolder  {    //ThreadLocal<T>变量用于保存当前线程的共享变量
    private static final ThreadLocal<RequestAttributes> requestAttributesHolder =            new NamedThreadLocal<RequestAttributes>("Request attributes");    private static final ThreadLocal<RequestAttributes> inheritableRequestAttributesHolder =            new NamedInheritableThreadLocal<RequestAttributes>("Request context");    /**
     * 将线程中的共享变量清除掉,会在RequetContextListner的destory()方法中调用。     */
    public static void resetRequestAttributes() {        //清空变量        requestAttributesHolder.remove();
        inheritableRequestAttributesHolder.remove();
    }    //过渡方法
    public static void setRequestAttributes(RequestAttributes attributes) {
        setRequestAttributes(attributes, false);
    }    // 核心的方式:将RequetAttrubutes(Request/Response/Session)放入到ThreadLocal<T>中进行共享
    public static void setRequestAttributes(RequestAttributes attributes, boolean inheritable) {        if (attributes == null) {
            resetRequestAttributes();
        }        else {            if (inheritable) {
                inheritableRequestAttributesHolder.set(attributes);
                requestAttributesHolder.remove();
            }            else {
                requestAttributesHolder.set(attributes);
                inheritableRequestAttributesHolder.remove();
            }
        }
    }

seo优化培训,网络推广培训,网络营销培训,SEM培训,网络优化,在线营销培训

 

2.3 ServletRequestAttributes

seo优化培训,网络推广培训,网络营销培训,SEM培训,网络优化,在线营销培训

public class ServletRequestAttributes extends AbstractRequestAttributes {    private final HttpServletRequest request;    private HttpServletResponse response;    private volatile HttpSession session;    private final Map<String, Object> sessionAttributesToUpdate = new ConcurrentHashMap<String, Object>(1);
}

seo优化培训,网络推广培训,网络营销培训,SEM培训,网络优化,在线营销培训

 

三、使用方法

从以上可以知道RuquetAttribute是放在了ThreadLocal中,则在该次请求中,可以在任意的代码位置中获取该该对象,由此拿到HttpServletRequet等对象。

HttpServletRequest request =((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();

利用该方法可以在任意位置获取request对象.

四、总结

RequetContextListner主要作用就一个:

将本次请求的 ServletRequestAttributes 对象 保存在ThreadLocal中,方便在某一次请求的任意代码位置获取(包括直接在service层获取)。

 

######################################LiuCF############转载注明出处###############2017年6月22日23:38:49###########################

http://www.cnblogs.com/LiuChunfu/p/7067828.html

延伸阅读

第一次在团队中担当组织者-Java培训,做最负责任的教育,学习改变命运,软件学习,再就业,大学生如何就业,帮大学生找到好工作,lphotoshop培训,电脑培训,电脑维修培训,移动软件开发培训,网站设计培训,网站建设培训第一次在团队中担当组织者