零、引言

RequetContextListener從名字結尾Listener來看就知道屬于監(jiān)聽器。

所謂監(jiān)聽器就是監(jiān)聽某種動作,在其開始(初始化)和結束(銷毀)的時候進行某些操作。

由此可以猜測:該類用于在RequetContext(請求上下文對象)創(chuàng)建和銷毀的時候進行某些操作(哪些操作?結尾總結!)

一、web.xml配置

要使用該listener對象需要在web.xml中進行如下配置。

<!-- 此監(jiān)聽器是監(jiān)聽HttpRequest對象,方便ContextHolderUtils程序調用HttpRequest對象 --><listener><description>request監(jiān)聽器</description><listener-class>org.springframework.web.context.request.RequestContextListener</listener-class></listener>

 

二、三個重要類解讀

2.1 RequetContextListener

seo優(yōu)化培訓,網絡推廣培訓,網絡營銷培訓,SEM培訓,網絡優(yōu)化,在線營銷培訓

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優(yōu)化培訓,網絡推廣培訓,網絡營銷培訓,SEM培訓,網絡優(yōu)化,在線營銷培訓

 

 2.2 RequetContextHolder

seo優(yōu)化培訓,網絡推廣培訓,網絡營銷培訓,SEM培訓,網絡優(yōu)化,在線營銷培訓

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優(yōu)化培訓,網絡推廣培訓,網絡營銷培訓,SEM培訓,網絡優(yōu)化,在線營銷培訓

 

2.3 ServletRequestAttributes

seo優(yōu)化培訓,網絡推廣培訓,網絡營銷培訓,SEM培訓,網絡優(yōu)化,在線營銷培訓

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優(yōu)化培訓,網絡推廣培訓,網絡營銷培訓,SEM培訓,網絡優(yōu)化,在線營銷培訓

 

三、使用方法

從以上可以知道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