Controller中加参数

@Controller
public class TestController {
@RequestMapping("/test")
public void test(HttpServletRequest request) {
......
}
}

Controller中获取request对象后,如果要在其他方法中(如service方法、工具类方法等)使用request对象,需要在调用这些方法时将request对象作为参数传入

此时request对象是方法参数,相当于局部变量,毫无疑问是线程安全的。

自动注入

@Controller
public class TestController{ @Autowired
private HttpServletRequest request; //自动注入request @RequestMapping("/test")
public void test() throws InterruptedException{
......
}
}

使用这种方式,当Bean(本例的TestController)初始化时,Spring并没有注入一个request对象,而是注入了一个代理(proxy);当Bean中需要使用request对象时,通过该代理获取request对象。request实际上是一个代理:代理的实现参见AutowireUtils的内部类ObjectFactoryDelegatingInvocationHandler。

调用request的方法method时,实际上是调用了由objectFactory.getObject()生成的对象的method方法;objectFactory.getObject()生成的对象才是真正的request对象。

objectFactory的类型为WebApplicationContextUtils的内部类RequestObjectFactory;而RequestObjectFactory要获得request对象需要先调用currentRequestAttributes()方法获得RequestAttributes对象,生成RequestAttributes对象的核心代码在类RequestContextHolder中,生成的RequestAttributes对象是线程局部变量(ThreadLocal),因此request对象也是线程局部变量;这就保证了request对象的线程安全性。

基类中自动注入

public class BaseController {
@Autowired
protected HttpServletRequest request;
}
@Controller
public class TestController extends BaseController {
}

与方法2相比,避免了在不同的Controller中重复注入request;但是考虑到java只允许继承一个基类,所以如果Controller需要继承其他类时,该方法便不再好用。

手动调用

@Controller
public class TestController {
@RequestMapping("/test")
public void test() throws InterruptedException {
HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest();
.......
}
}

通过自动注入实现与通过手动方法调用实现原理差不多。因此本方法也是线程安全的。

优点:可以在非Bean中直接获取。缺点:如果使用的地方较多,代码非常繁琐;因此可以与其他方法配合使用。

@ModelAttribute方法

@Controller
public class TestController {
private HttpServletRequest request; 此处线程不安全
@ModelAttribute
public void bindRequest(HttpServletRequest request) {
this.request = request; 此处request线程安全
}
@RequestMapping("/test")
public void test() throws InterruptedException {
......
}
}

@ModelAttribute注解用在Controller中修饰方法时,其作用是Controller中的每个@RequestMapping方法执行前,该方法都会执行。bindRequest()的作用是在test()执行前为request对象赋值。虽然bindRequest()中的参数request本身是线程安全的,但由于TestController是单例的,request作为TestController的一个域,无法保证线程安全。

SpringMvc中获取Request的更多相关文章

  1. springMVC中获取request和response对象的几种方式(RequestContextHolder)

    springMVC中获取request和response对象的几种方式 1.最简单方式:参数 2.加入监听器,然后在代码里面获取 原文链接:https://blog.csdn.net/weixin_4 ...

  2. 在SpringMVC中获取request对象

    1.注解法 @Autowired private  HttpServletRequest request; 2. 在web.xml中配置一个监听 <listener> <listen ...

  3. 在SpringMVC中获取request对象的几种方式

    1.最简单的方式(注解法) @Autowired private HttpServletRequest request; 2.最麻烦的方法 a. 在web.xml中配置一个监听 <listene ...

  4. 如何在SpringMVC中获取request对象

    1.注解法 @Autowired private HttpServletRequest request; <listener> <listener-class> org.spr ...

  5. springmvc中获取request对象,加载biz(service)的方法

    获取request对象: 首先配置web.xml文件--> <listener> <listener-class> org.springframework.web.con ...

  6. struts2中获取request、response,与android客户端进行交互(文件传递给客户端)

    用struts2作为服务器框架,与android客户端进行交互需要得到request.response对象. struts2中获取request.response有两种方法. 第一种:利用Servle ...

  7. spring mvc controller中获取request head内容

    spring mvc controller中获取request head内容: @RequestMapping("/{mlid}/{ptn}/{name}") public Str ...

  8. Spring中获取request的几种方法,及其线程安全性分析

    前言 本文将介绍在Spring MVC开发的web系统中,获取request对象的几种方法,并讨论其线程安全性. 原创不易,如果觉得文章对你有帮助,欢迎点赞.评论.文章有疏漏之处,欢迎批评指正. 欢迎 ...

  9. 【转】SpringMVC,获取request的几种方法,及线程安全性

    作者丨编程迷思 https://www.cnblogs.com/kismetv/p/8757260.html 概述 在使用Spring MVC开发Web系统时,经常需要在处理请求时使用request对 ...

随机推荐

  1. [COCI2013]DLAKAVAC

    [COCI2013]DLAKAVAC 题目大意: 有一个长度为\(m(m\le1500)\)的\(01\)串\(A\),进行\(k(k\le10^{18})\)次操作.一次操作完的串中若\(A_i=1 ...

  2. fastjson 使用教程

    fastjson 是阿里的开源项目,具网上的说法 fastjson 的解析速度是 Gson 的6倍,体积小,而且开源. 项目地址: https://github.com/alibaba/fastjso ...

  3. Linux硬盘管理

    管理好硬盘/dev/xxynsd SCSI SATA USBhd IDE主分区扩展分区 1-4逻辑分区5以后fdisk -l 硬盘名/分区名fdisk -l /dev/sda 如何给硬盘分区?把500 ...

  4. bzo1606: [Usaco2008 Dec]Hay For Sale 购买干草

    1606: [Usaco2008 Dec]Hay For Sale 购买干草 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1338  Solved: 9 ...

  5. TFS 安装 扩展包

    TFS 2015以后的版本支持安装扩展插件,我们可以自己开发插件,也可以从市场上下载. 市场地址为:http://go.microsoft.com/fwlink/?LinkId=722825& ...

  6. css中px,em,rem,rpx的区别

    今天看到一个面试题为 px,em的区别,为了更好地让读者区分css的长度单位,我总结下css中常用的长度单位: px,em,rem,rpx 像素px是我们在定义CSS中经常用到的尺寸大小单位,而em在 ...

  7. centos7下安装配置redis

    1.1. Redis下载安装(linux) 1.1.1. 下载: 下载地址:https://redis.io/download 选择合适的版本下载,如下图: 1.1.2. 安装: (1)把下载好的re ...

  8. java大数BinInteger

    当我们遇到long不行的时候就要考虑这个BinInteger了,因为这是只要你内存够大,就能输入很大的数,用这个处理高精度问题,是很容易的一件事,对于我这刚学java的萌新来说,长见识了,确实比C方便 ...

  9. json获取数据生成动态菜单(转)

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  10. JDBC(13)—JDBC调用存储过程和函数

    步骤: JDBC调用存储过程和函数 步骤: ①:通过Connection对象的prepareCall()方法创建一个CallableStatement对象的实例,在使用Connection对象的pre ...