Spring 中 HttpServletRequest 作为成员变量是安全的吗?
在使用spring框架开发的时候,经常会在controller类中看到 HttpServletRequest 对象参数,一般我们都是直接使用,但是它是何时、怎么注入到 spring 容器的呢 ?另外以成员变量注入的 request 是线程安全的吗 ?
@Controller
public class SomeController {@Resourceprivate HttpServletRequest request1;@RequestMapping("/test")public String test2(HttpServletRequest request2) {System.out.println(request1.getQueryString());System.out.println(request2.getQueryString());return "";}}
1、request 成员变量是否线程安全 ?
先说结论:注入request这个成员变量是线程安全的,来看下 spring 是如何做到的,先 debug 看下两种做法真实注入类的区别
可以看出成员变量注入的是代理对象AutowireUtils.ObjectFactoryDelegatingInvocationHandler ,而作为方法参数注入的就是我们一般使用的Request对象,先看下 AutowireUtils 的内部类ObjectFactoryDelegatingInvocationHandler
/*** Reflective InvocationHandler for lazy access to the current target object.*/
@SuppressWarnings("serial")
private static class ObjectFactoryDelegatingInvocationHandler implements InvocationHandler, Serializable {private final ObjectFactory<?> objectFactory;public ObjectFactoryDelegatingInvocationHandler(ObjectFactory<?> objectFactory) {this.objectFactory = objectFactory;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {String methodName = method.getName();if (methodName.equals("equals")) {// Only consider equal when proxies are identical.return (proxy == args[0]);} else if (methodName.equals("hashCode")) {// Use hashCode of proxy.return System.identityHashCode(proxy);} else if (methodName.equals("toString")) {return this.objectFactory.toString();}try {return method.invoke(this.objectFactory.getObject(), args);}catch (InvocationTargetException ex) {throw ex.getTargetException();}}
}
当代理对象的方法被调用时,除去少数几个方法,大部分的情况都是通过this.objectFactory.getObject() 获取被代理对象,再调用被代理对象的相应方法
进一步 debug,终于看到了熟悉的Request类,可以看到它是从 requestAttributesHolder 中取到的,那么requestAttributesHolder又是什么?
RequestContextHolder的ThreadLocal成员变量就是实现的关键所在,它存放了每个线程对应的Request对象,因此在@Controller中调用作为成员变量注入的代理类的方法时,最终可以取到当前线程相对应的Request对象,并调用Request对应的方法,这样@Controller中的成员变量不需要重复注入(它一直都是最初bean初始化时注入的代理类),也避免了线程不安全的问题。
2、spring是何时将Request放入这个ThreadLocal之中的 ?
同样先说结论:在 Springmvc 的 dispatcherServlet 的父类 FrameworkServlet 里完成的,分析代码实现
所有的请求调用到 Servlet 的doGet、dePost 时,最终都会通过 processRequest(request, response) 进行处理
processRequest 方法在调用了 initContextHolders(request, localeContext, requestAttributes) 时会将Request放入ThreadLocal,方便后续线程安全的获取
3、总结
1、在bean中注入成员变量 HttpServletRequest 时,实际注入的是 spring 框架生成的代理对象 ObjectFactoryDelegatingInvocationHandler 的实例。在我们实际调用这个成员变量的方法时,会调用 objectFactory 的 getObject() 对象对应的方法(objectFactory 是RequestObjectFactory 这个类的对象)
2、RequestObjectFactory 的 getObject 方法是从RequestContextHolder的threadlocal 中去取值的。
3、请求刚进入 springmvc 的 dispatcherServlet 时,会把 request 相关对象设置到RequestContextHolder 的 threadlocal 中去,方便后续线程安全的获取
相关文章:

Spring 中 HttpServletRequest 作为成员变量是安全的吗?
在使用spring框架开发的时候,经常会在controller类中看到 HttpServletRequest 对象参数,一般我们都是直接使用,但是它是何时、怎么注入到 spring 容器的呢 ?另外以成员变量注入的 request 是线程安全的吗 ? Controller public c…...

浅聊雷池社区版(WAF)的tengine
雷池社区版是一个开源的免费Web应用防火墙(WAF),专为保护Web应用免受各种网络攻击而设计。基于强大的Tengine,雷池社区版提供了一系列先进的安全功能,适用于中小企业和个人用户。 Tengine的故事始于2011年,…...

如何安装配置VisualSVN服务并实现公网访问本地服务【内网穿透】
文章目录 前言1. VisualSVN安装与配置2. VisualSVN Server管理界面配置3. 安装cpolar内网穿透3.1 注册账号3.2 下载cpolar客户端3.3 登录cpolar web ui管理界面3.4 创建公网地址 4. 固定公网地址访问 前言 SVN 是 subversion 的缩写,是一个开放源代码的版本控制系统…...

解析TZ字样的0时区UTC时间格式化为东八区
带TZ字样的0时区UTC时间格式化为东八区 TZ 的Z是zero timezone 0时区的意思。带TZ的时间是UTC0的时间SimpleDateFormat默认使用系统日历时区,必须手动指定0时区,才能正确解析TZ时间详细测试代码见下: SneakyThrows public static void main…...

python两数之和
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。 你可以按任意顺序返回…...

PBR材质背光面太暗优化
图形学中漫反射光照遵循兰伯特光照模型,它的公式如下 其中: :漫反射光颜色 :入射光颜色 :材质的漫反射系数 :法线方向 :光源方向 由于背光面的法线方向和光源方向的点积为负数,因此…...

【电力电子在电力系统中的应用】6 滞环电流控制的PWM整流器 + STATCOM整流器 + APF仿真
【仅供参考】 【2023.06西南交大电力电子在电力系统中的应用】 目录 步骤一:基于滞环电流控制的PWM整流器仿真 1.1 仿真要求 1.2 仿真电路原理及设计 1.2.1 主电路的搭建 1.2.2 控制电路的搭建 1.3 波形分析 步骤二:从PWM整流器到STATCOM仿真 2…...

接近8000字的SpringSpring常用注解总结!安排
接近8000字的Spring/Spring常用注解总结!安排 为什么要写这篇文章? 最近看到网上有一篇关于 SpringBoot 常用注解的文章被转载的比较多,我看了文章内容之后属实觉得质量有点低,并且有点会误导没有太多实际使用经验的人ÿ…...

51单片机_智能家居终端
实物演示效果: https://www.bilibili.com/video/BV1bh4y1A7ZW/?vd_source6ff7cd03af95cd504b60511ef9373a1d 51单片机是否适合做多功能智能家居控制系统?51单片机的芯片是否具有与WiFi通信的能力?如果有的话,具体有哪些芯片啊&a…...

css实现动态水波纹效果
效果如下: 外层容器 (shop_wrap): 设置外边距 (padding) 提供一些间距和边距 圆形容器 (TheCircle): 使用相对定位 (position: relative),宽度和高度均为 180px,形成一个圆形按钮圆角半径 (border-radius) 设置为 50%&…...

Chrome 开发者工具
Chrome 开发者工具 介绍控制面板时间线下载信息概要请求列表单个请求时间线优化时间线上耗时项 lighthouse 插件Performance(性能指标)Accessibility(可访问性)Best Practices(最佳实践)SEO(搜索…...

Error: error:0308010C:digital envelope routines::unsupported的解决方案
因为最近安装了pnpm对node版本有要求,升级了node版本是18以后,在运行之前的项目,就跑不起来了,报错如下: Error: error:0308010C:digital envelope routines::unsupported解决方案一: node版本切换到16版…...

vue基于spring boot框架的发艺美发店理发店管理系统的设计q9xpe
店铺信息、美发信息是发艺美发店管理系统的重要组成部分,信息清晰、详细、准确,能够有效地促进发艺美发店管理系统的运行[5]。基础设定函数是对整个系统的总体布局进行合理安排,包括:店铺活动、物品信息、领用信息等。通过对各类资…...

JS取余运算符 %,ES2023 新增数组方法Array.at
取余运算符(%)的作用就是用来两个操作数进行相除运算之后的余数。 注意,两个操作数取余是有循环范围的,这个范围为 0 - 第二个参数 - 1。 如下图: 对于6取余的话,得到的取余数据就会一直在0-5之间进行循环…...

unity SqLite读取行和列
项目文件 链接:https://pan.baidu.com/s/1BabHvQ-y0kX_w15r7UvIGQ 提取码:emsg –来自百度网盘超级会员V6的分享 using System.Collections; using System.Collections.Generic; using UnityEngine; using Mono.Data.Sqlite; using System; using Syste…...

使用docker部署RStudio容器并结合内网穿透实现公网访问
文章目录 前言1. 安装RStudio Server2. 本地访问3. Linux 安装cpolar4. 配置RStudio server公网访问地址5. 公网远程访问RStudio6. 固定RStudio公网地址 前言 RStudio Server 使你能够在 Linux 服务器上运行你所熟悉和喜爱的 RStudio IDE,并通过 Web 浏览器进行访问…...

adb wifi 远程调试 安卓手机 命令
使用adb wifi 模式调试需要满足以下前提条件: 手机 和 PC 需要在同一局域网下。手机需要开启开发者模式,然后打开 USB 调试模式。 具体操作步骤如下: 将安卓手机通过 USB 线连接到 PC。(连接的时候,会弹出请求&#x…...

Android Activity的启动流程(Android-10)
前言 在Android开发中,我们经常会用到startActivity(Intent)方法,但是你知道startActivity(Intent)后Activity的启动流程吗?今天就专门讲一下最基础的startActivity(Intent)看一下Activity的启动流程,同时由于Launcher的启动后续…...

flask不使用flask-login插件
由于flask版本升级问题,flask-manager里面的Command命令高版本不支持,低版本的兼容flask-sqlalchemy启动也会报错,第三方插件有很多问题,所以痛定思痛决定放弃使用这个,使用flask自带语法自己写一个 类似于django继承…...

1. SpringBoot3 基础
文章目录 1. SpringBoot 概述2. SpringBoot 入门3. SpringBoot 配置文件3.1 SpringBoot 配置文件基本使用3.2 yml 配置文件 4. SpringBoot 整合 Mybatis5. Bean 管理5.1 Bean 扫描5.2 Bean 注册5.3 注册条件 6. 组合注解7. 自动配置原理8. 自定义 Starter 1. SpringBoot 概述 …...

美易官方:苹果承认GPU安全漏洞存在:iPhone 12和M2系列受影响
苹果承认GPU安全漏洞存在: iPhone 12和M2 MacBook Air受影响 近日,苹果公司承认其部分产品存在GPU安全漏洞,这些漏洞可能会影响iPhone 12和M2 MacBook Air等设备的安全性。这一消息引起了广泛的关注和担忧,因为这些设备是许多用户…...

【Vue3】3-1 : 章节介绍 - Vue3组件应用及单文件组件
本书目录:点击进入 一、本章学习目标 二、课程安排 一、本章学习目标 Vue3组件相关概念掌握组件之间的通信封装一个可复用的组件单文件组件SFC:即.vue文件 样式 结构 逻辑脚手架的使用和底层实现机制工程化的认知 二、课程安排 组件的概念及组件的基…...

【数据结构】二叉树(遍历,递归)
🌈个人主页:秦jh__https://blog.csdn.net/qinjh_?spm1010.2135.3001.5343🔥 系列专栏:《数据结构》https://blog.csdn.net/qinjh_/category_12536791.html?spm1001.2014.3001.5482 目录 二叉树遍历规则 前序遍历 …...

《微信小程序开发从入门到实战》学习八十五
6.15 设备API 6.15.2 添加联系人API 使用wx.addPhoneContact接口可以在用户的手机通讯录中添加联系人信息。用户可以选择“新增联系人”或“添加到已有联系人”。该接口接受Object参数,参支持属性如下所示: firstName:必填,名字…...

设计模式——命令模式
命令模式(Command Pattern)是一种行为型设计模式,它将一个请求封装为一个对象,使发出请求的对象和执行请求的对象解耦。这样可以方便地对请求排队、记录日志、撤销/重做操作以及支持可扩展性。 原理 命令接口(Comman…...

Modbus协议学习第三篇之协议通信规则
导语 本篇博客将深入介绍Modbus协议的一些内容,主要包括通讯方式和通讯模型的介绍 Modbus通讯方式 Modbus协议是单主机、多从机的通信协议,即同一时间,总线上只能有一个主设备,但可以有一个或者多个从设备(最多好像是2…...

git仓库使用说明
Git软件使用 1.先下载git相关软件 下载地址: Git - Downloading Package (git-scm.com) 下载其中一个安装 2.打开gitee网站,注册账号 3.打开个人中心,选择ssh公钥,查看如何生成公钥 4.生成公钥后,添加相应的公钥 …...

边缘计算和联邦学习的联系
1. 什么是边缘计算? 边缘计算(Edge Computing)是一种计算模型,其主要思想是将计算、存储和数据处理能力推送到离数据源近的边缘设备,而不是依赖于远程的云服务器。这样做的目的是减少数据传输延迟、提高响应速度&…...
机器学习算法理论:贝叶斯
贝叶斯定理对于机器学习来说是经典的概率模型之一,它基于先验信息和数据观测来得到目标变量的后验分布。具体来说,条件概率(也称为后验概率)描述的是事件A在另一个事件B已经发生的条件下的发生概率,公式表示为P(A|B)&a…...

229.【2023年华为OD机试真题(C卷)】手机App防沉迷系统(模拟-JavaPythonC++JS实现)
🚀点击这里可直接跳转到本专栏,可查阅顶置最新的华为OD机试宝典~ 本专栏所有题目均包含优质解题思路,高质量解题代码(Java&Python&C++&JS分别实现),详细代码讲解,助你深入学习,深度掌握! 文章目录 一. 题目-手机App防沉迷系统二.解题思路三.题解代码Pyth…...