来自:https://www.cnblogs.com/softidea/p/7068196.html

零、引言

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

  //ServletRequestListener web中的监听器,该监听器主要在创建request,销毁request对象起作用
public class RequestContextListener implements ServletRequestListener {
private static final String REQUEST_ATTRIBUTES_ATTRIBUTE =
RequestContextListener.class.getName() + ".REQUEST_ATTRIBUTES";
// 在请求进入的时候,初始化变量放入ThreadLocal<T>中 ,创建request对象
@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) {
...
}
}

2.2 RequetContextHolder

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();
}
}
}

2.3 ServletRequestAttributes

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);
}

三、使用方法

从以上可以知道RuquetAttribute是放在了ThreadLocal中,则在该次请求中,可以在任意的代码位置中获取该该对象,由此拿到HttpServletRequet等对象。
HttpServletRequest request =((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
利用该方法可以在任意位置获取request对象.

四、总结

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

最新文章

  1. eclipse插件开发入门
  2. [转]非OpenVZ下利用谷歌TCP-BBR协议单边加速你的VPS
  3. SqlServer 的提示符(Option/With等提示符)不是什么时候都可以用的
  4. c实现的iOS http下载类。支持自己设定http 头(比如cookie等)
  5. hdu 5272 Dylans loves numbers
  6. loading-show-hide
  7. javaweb之servlet 全解
  8. 【失败】制作CentOS镜像
  9. license文件生成原理
  10. C#:根据银行卡卡号推断银行名称
  11. hdu 3440 House Man
  12. 转: Windows下安装Oracle Database 12c Release 1(12.1.0.2.0) - Enterprise Edition
  13. 在Intellij IDEA中使用Maven的方式将项目导出为jar包
  14. Fiddler安装证书
  15. R语言三元相图的做法
  16. 使用fiddler轻轻松松制造客户端接口time out的情况
  17. bzoj千题计划247:bzoj4903: [Ctsc2017]吉夫特
  18. SpringBoot配置属性之MVC
  19. boolean类型的按位或||和|的区别
  20. oracle 制定定时任务

热门文章

  1. 数字图像处理实验(5):PROJECT 04-01 [Multiple Uses],Two-Dimensional Fast Fourier Transform 标签: 图像处理MATLAB数字图像处理
  2. Luogu 1979 [NOIP2013] 华容道
  3. Mat_类
  4. mono-3.0.2安装指南
  5. 《Maven实战》笔记-9-版本管理
  6. WebGoat系列实验Access Control Flaws
  7. 【zookeeper】
  8. mysql服务启动不了解决方法
  9. loj #2006. 「SCOI2015」小凸玩矩阵
  10. cron定时备份数据库