springboot如何把HttpServletRequest传入到controller

HttpServletRequest是由如tomcat这种Servlet容器创建的。
Tomcat 创建的 Request 和 Response 的类结构图。

至于这个HttpServletRequest是怎么传到你对应的controller方法内的,实际上就是SpringMVC里面的DispatchServlet起的作用。这里先不展开,下面再讨论,先看一张图。

得到HttpServletRequest的三种方式

方式一:Controller方法参数

Controller的方法参数上写上HttpServletRequest,这样每次请求过来得到就是对应的HttpServletRequest

 
  1. @GetMapping("/test")

  2. public void test(HttpServletRequest request) {}

方式二:从RequestContextHolder上下文获取

 
  1. // 从请求上下文里获取Request对象

  2. ServletRequestAttributes requestAttributes = ServletRequestAttributes.class.

  3. cast(RequestContextHolder.getRequestAttributes());

  4. HttpServletRequest contextRequest = requestAttributes.getRequest();

方式三:依赖注入@Autowired

 
  1. @Autowired

  2. HttpServletRequest req;

  3. @GetMapping("/test")

  4. public void test(HttpServletRequest request) {}

注入的request何处来?

发现是注入其实是往WebApplicationContextUtils通过RequestObjectFactory拿值,跟踪

返回的是RequestContextHolder里的值. 追踪RequestContextHolder

每次返回的其实是, RequestAttributes的实现类ServletWebRequest(ServletRequestAttributes)里的request. 因为RequestAttributes是属于threadLocal的,所以注入的request也是线程安全的了

2, spring何时设置的request对象?

HttpServlet实现类 FrameworkServlet-> service()->processRequst()

每次请求都会往里面设置最新的request, 设值

================================================================

我们可以在Spring的bean中轻松的注入HttpServletRequest,使用@Autowired HttpServletRequest request;就可以了。

但是,为什么我们可以直接这样用呢?

原因肯定是Spring在容器初始化的时候就将HttpServletRequest注册到了容器中

那么我们就查原码,发现在WebApplicationContextUtils.registerWebApplicationScopes(ConfigurableListableBeanFactory, ServletContext)中实现了这个功能。

这个方法是在AbstractApplicationContext.refresh()中进行调用的,也就是在Spring容器初始化的时候,将web相关的对象注册到了容器中。

具体可以看下面的原码图片:

附:

1. Spring能实现在多线程环境下,将各个线程的request进行隔离,且准确无误的进行注入,奥秘就是ThreadLocal

2. Spring中还可以直接注入ApplicationContext

作者:三也视界
链接:https://www.jianshu.com/p/a37aa4c0295e
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值