零、引言

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. 搭建本地git仓库

    使用工具:git|码云 步骤: 注册码云账号,创建项目名称等. 本地git配置 本地文件目录:git init(初始化创建分支master) 基础配置:git config --global user ...

  2. 1018 Big Number

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission( ...

  3. C++ 元编程 —— 让编译器帮你写程序

    目录 1 C++ 中的元编程 1.1 什么是元编程 1.2 元编程在 C++ 中的位置 1.3 C++ 元编程的历史 2 元编程的语言支持 2.1 C++ 中的模板类型 2.2 C++ 中的模板参数 ...

  4. 思考题:用Use Case获取需求的方法是否有什么缺陷,还有什么地方需要改进?(提示:是否对所有的应用领域都适用?使用的方便性?.......)

    思考题: 用Use Case获取需求的方法是否有什么缺陷,还有什么地方需要改进?(提示:是否对所有的应用领域都适用?使用的方便性?.......) 简答: 一.用例解释: 在软件工程中,用例是一种在开 ...

  5. .net数据统计系统设计(中小型)

    近一年多没在博客园写东西了,从换公司后就一直努力学习公司的框架和业务.而今接手一个电商数据统计项目,在博客园搜索统计项目解决方案却一无所获,最终自己设计并在开发的过程中持续更新,希望可以和大家一起交流 ...

  6. Eclipse常用的6个Debug技巧

    1. Ctrl+Shift+i: Person father = new Person(); father.setName("father"); System.out.printl ...

  7. 腾讯云更换yum源

    最近公司使用了云服务器代替了机房的一些服务器,然而选择了腾讯云,个人观点通过比较还是阿里云好了点,可能为了使用腾讯云的一些其他功能吧,书归正文. 由于腾讯的源网站经常挂,在我使用过的一台腾讯云主机的时 ...

  8. git常用命令记录

    配置本地仓库 git config --global user.name.git config --global user.email 查看配置详情 git config -l 初始仓库 git in ...

  9. ios runtime 打印内 内部调用的属性

    unsigned int count = 0; // 拷贝出所有的成员变量列表 Ivar *ivars = class_copyIvarList([UITextField class], &c ...

  10. R语言的高质量图形渲染库Cairo(转)

    前言 R语言不仅在统计分析,数据挖掘领域,计算能力强大.在数据可视化上,也不逊于昂贵的商业.当然,背后离不开各种开源软件包的支持,Cairo就是这样一个用于矢量图形处理的类库. Cairo可以创建高质 ...