零、引言

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

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) {
...
}
}

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层获取)。
 
######################################LiuCF############转载注明出处###############2017年6月22日23:38:49###########################
 
 

由SpringMVC中RequetContextListener说起的更多相关文章

  1. SpringMVC中RequetContextListener

    来自:https://www.cnblogs.com/softidea/p/7068196.html 零.引言 RequetContextListener从名字结尾Listener来看就知道属于监听器 ...

  2. SpringMvc中的数据校验

    SpringMvc中的数据校验 Hibernate校验框架中提供了很多注解的校验,如下: 注解 运行时检查 @AssertFalse 被注解的元素必须为false @AssertTrue 被注解的元素 ...

  3. 【Spring】SpringMVC中浅析Date类型数据的传递

    在控制器中加入如下代码: @InitBinder public void initBinder(ServletRequestDataBinder bin){ SimpleDateFormat sdf ...

  4. 详解SpringMVC中GET请求

    GET请求概述 GET请求,请求的数据会附加在URL之后,以?分割URL和传输数据,多个参数用&连接.URL的编码格式采用的是ASCII编码,而不是uniclde,所有的非ASCII字符都要编 ...

  5. SpringMVC中使用Interceptor拦截器

    SpringMVC 中的Interceptor 拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的处理.比如通过它来进行权限验证,或者是来判断用户是否登陆,或者是像12306 那 ...

  6. 如何在springMVC 中对REST服务使用mockmvc 做测试

    如何在springMVC 中对REST服务使用mockmvc 做测试 博客分类: java 基础 springMVCmockMVC单元测试  spring 集成测试中对mock 的集成实在是太棒了!但 ...

  7. springMVC 返回类型选择 以及 SpringMVC中model,modelMap.request,session取值顺序

    springMVC 返回类型选择 以及 SpringMVC中model,modelMap.request,session取值顺序 http://www.360doc.com/content/14/03 ...

  8. SpringMVC中使用Cron表达式的定时器

    SpringMVC中使用Cron表达式的定时器 cron(定时策略)简要说明 顺序: 秒 分 时 日 月 星期 年份 (7个参数,空格隔开各个参数,年份非必须参数) 通配符: , 如果分钟位置为* 1 ...

  9. SpringMVC中使用Json传数据

    在web项目中使用Json进行数据的传输是非常常见且有用的,在这里介绍下在SpringMVC中使用Json传数据的一种方法,在我的使用中,主要包括下面四个部分(我个人喜好使用maven这类型工具进行项 ...

随机推荐

  1. Spring boot 默认静态资源路径与手动配置访问路径

    在application.propertis中配置 ##端口号server.port=8081 ##默认前缀spring.mvc.view.prefix=/## 响应页面默认后缀spring.mvc. ...

  2. Java中实现String.padLeft和String.padRight

    因为习惯了C#中的padLeft和padRight,接触Java后突然失去这两个功能,觉得别扭,就试着实现了这两个方法. Java中String.format()中带有字符串对齐功能如下: Syste ...

  3. jQuery选择器---基本选择器总结

    今天要跟大家分享一下jQuery选择器的使用方法,它的选择器分为四大类 如图: 基本选择器的使用: 1.id选择器 案例: <div id="notMe"><p& ...

  4. lightOJ 1017 Brush (III) DP

    题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1017 搞了一个下午才弄出来,,,,, 还是线性DP做的不够啊 看过数据量就知道 ...

  5. Elasticsearch中的相似度模型(原文:Similarity in Elasticsearch)

    原文链接:https://www.elastic.co/blog/found-similarity-in-elasticsearch 原文 By Konrad Beiske 翻译 By 高家宝 译者按 ...

  6. 介绍几个python的音频处理库

    一.eyeD3 直接在google上搜索python mp3 process ,推荐比较多的就是这个第三方库了.先来看看官方介绍吧. About eyeD3 is a Python tool for ...

  7. linux下登陆MongoDB的两种方式

    第一种:不带auth认证的 第二种:需要带auth认证的(即需要用户名和密码的) 当指定用户名和密码在查看数据,发现就可以看得到了 查看文章:开启MongoDB客户端访问控制

  8. java虚拟机学习-JVM调优总结-分代垃圾回收详述(9)

    为什么要分代 分代的垃圾回收策略,是基于这样一个事实:不同的对象的生命周期是不一样的.因此,不同生命周期的对象可以采取不同的收集方式,以便提高回收效率. 在Java程序运行的过程中,会产生大量的对象, ...

  9. 重构了cxlt-vue2-toastr插件

    距离上篇文章已经过去一个多月了,期间有很多想法,但时间真不是想挤就能挤出来的.其实这段时间我就做了一件事,一个小程序的项目,已上线半月有余,也迭代了几个版本,现在还在不断完善. 先说点题外话,我们做了 ...

  10. 快速找到ARP病毒源

    第一招:使用Sniffer抓包 在网络内任意一台主机上运行抓包软件,捕获所有到达本机的数据包.如果发现有某个IP不断发送请求包,那么这台电脑一般就是病毒源.原理:无论何种ARP病毒变种,行为方式有两种 ...