Spring-web-HttpServletRequest

在spring mvc中,有2种方法获取当前http请求的request,分别如下

方式1: spring mvc将当前request从抽象类FrameworkServletprocessRequest方法中放进去,然后我们通过下面代码拿出来

HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();  
// 下面是顺便写的,与本文关系不大
HttpSession session = request.getSession();
//应用程序在电脑上的真实的硬盘路径
session.getServletContext().getRealPath("/");
//应用程序的访问路径,http://xxxx.xx/这种
request.getScheme()+"://"+request.getServerName()+":" +request.getServerPort()+request.getContextPath();

方式2: 使用依赖注入的方式获取当前请求的request,像下面这样,每次进来一个新的HTTP请求都会产生一个新的request

@RestController
public class AController {@Resourceprivate HttpServletRequest request;@RequestMapping("/test")public void test(){// 这个request不会因为多个请求并发而导致线程不安全,每个请求都有自己的requestSystem.out.println(request);}
}

本文着重讲一下方式2的源码入口,它是在WebApplicationContextUtils类的registerWebApplicationScopes方法里写死的,源代码如下,看注释那行就可以了,当服务启动的时候,会走该方法

	public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory,@Nullable ServletContext sc) {beanFactory.registerScope(WebApplicationContext.SCOPE_REQUEST, new RequestScope());beanFactory.registerScope(WebApplicationContext.SCOPE_SESSION, new SessionScope());if (sc != null) {ServletContextScope appScope = new ServletContextScope(sc);beanFactory.registerScope(WebApplicationContext.SCOPE_APPLICATION, appScope);// Register as ServletContext attribute, for ContextCleanupListener to detect it.sc.setAttribute(ServletContextScope.class.getName(), appScope);}// 代码就在这里,意思是说如果注入的类型是ServletRequest的子类,那么spring mvc会自动new一个// RequestObjectFactory,然后扔进去,也就是我们上述代码中的 private HttpServletRequest request;// 最后spring通过代理的方式,将我们的request硬改成ServletRequest类型的,然后我们调用request里的// 各种方法的时候,都是通过反射调用的beanFactory.registerResolvableDependency(ServletRequest.class, new RequestObjectFactory());beanFactory.registerResolvableDependency(ServletResponse.class, new ResponseObjectFactory());beanFactory.registerResolvableDependency(HttpSession.class, new SessionObjectFactory());beanFactory.registerResolvableDependency(WebRequest.class, new WebRequestObjectFactory());if (jsfPresent) {FacesDependencyRegistrar.registerFacesDependencies(beanFactory);}}

上面运行完毕之后,会走到AutowireUtils类的resolveAutowiringValue方法,这个类决定是否通过代理生成真正的注入对象,源码如下

public static Object resolveAutowiringValue(Object autowiringValue, Class<?> requiredType) {if (autowiringValue instanceof ObjectFactory && !requiredType.isInstance(autowiringValue)) {ObjectFactory<?> factory = (ObjectFactory<?>) autowiringValue;// 就是这个if,我们的代码写的是注入HttpServletRequest,但是实际值是上面的RequestObjectFactory// spring发现我们注入的值和实际值不匹配,会进入下面的if,然后生成一个代理类,改变我们的字段if (autowiringValue instanceof Serializable && requiredType.isInterface()) {autowiringValue = Proxy.newProxyInstance(requiredType.getClassLoader(),new Class<?>[] {requiredType}, new ObjectFactoryDelegatingInvocationHandler(factory));}else {return factory.getObject();}}return autowiringValue;}

本文就到这里,主要是找到了注入HttpServletRequest 类的入口,找到了入口,知道了spring也是通过枚举写死的方式来产生代理,最后达到每个请求都创建一个新的request的目的
相关内容:
Spring-beans-ObjectFactory
Spring-web-ObjectFactory

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/28565.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【计算机组成原理】指令系统考研真题详解之拓展操作码!

计算机组成原理&#xff1a;指令系统概述与深入解析 1. 指令系统概述 计算机软硬件界面的概念 在计算机组成原理中&#xff0c;指令系统扮演着至关重要的角色&#xff0c;它是计算机软硬件界面的核心。软件通过指令与硬件进行通信&#xff0c;硬件根据指令执行相应的操作。指…

装饰者模式(设计模式)

装饰模式就是对一个类进行装饰&#xff0c;增强其方法行为&#xff0c;在装饰模式中&#xff0c;作为原来的这个类使用者还不应该感受到装饰前与装饰后有什么不同&#xff0c;否则就破坏了原有类的结构了&#xff0c;所以装饰器模式要做到对被装饰类的使用者透明&#xff0c;这…

如何解决javadoc一直找不到路径的问题?

目录 一、什么是javadoc二、javadoc为什么会找不到路径三、如何解决javadoc一直找不到路径的问题 一、什么是javadoc Javadoc是一种用于生成Java源代码文档的工具&#xff0c;它可以帮助开发者生成易于阅读和理解的文档。Javadoc通过解析Java源代码中的注释&#xff0c;提取其…

英语角情景设计方案

背景介绍 在一个充满活力的清晨&#xff0c;项目团队汇集在线上会议中&#xff0c;准备开始他们定期的项目审查会议。团队成员不仅包括项目经理&#xff08;PM&#xff09;、客户代表&#xff0c;还有会计&#xff08;AM&#xff09;、设计师、前端开发者、后端开发者以及测试…

【CSS】background-size属性的作用是什么,怎么使用

background-size属性的作用&#xff1a; background-size属性在CSS中用于设置背景图像的尺寸。在CSS3之前&#xff0c;背景图片的尺寸是由图片的实际尺寸决定的。而在CSS3中&#xff0c;background-size属性允许我们规定背景图片的尺寸&#xff0c;这使得我们能够在不同的环境…

python命令行参数异常处理的方法:Exception getopt.GetoptError异常

一. 简介 前一篇文章学习了 针对 python的命令行参数进行处理时&#xff0c;提供的模块: getopt模块。文章如下&#xff1a; python3的基本语法&#xff1a;命令行参数-CSDN博客 本文继续学习 getopt模块的一个方法 getopt.GetoptError。 二. python命令行参数&#xff1a…

【Python】理解『下采样』:原理与应用

是你多么温馨的目光 教我坚毅望着前路 叮嘱我跌倒不应放弃 没法解释怎可报尽亲恩 爱意宽大是无限 请准我说声真的爱你 &#x1f3b5; Beyond《真的爱你》 在数字信号处理、图像处理和机器学习中&#xff0c;下采样&#xff08;Downsampling&#xff09;是…

42 mysql “+“ 操作符的实现

前言 问题来自于 chinaunix, mysql select 子句的小白问题 mysql 的一些基础的 算术运算符 的计算的实现 这里 整理如下 case, 执行之前 设置如下变量 set a 2; set b 3;select a b; select a b; select 1 3; select 1 3; select a b; select a b; select a b; …

【Quartus 13.0】NIOS II 部署UART 和 PWM

打算在 EP1C3T144I7 芯片上部署 nios ii 做 uart & pwm控制 这个芯片或许不够做 QT 部署 这个芯片好老啊&#xff0c;但是做控制足够了&#xff0c;我只是想装13写 leader给的接口代码是用VHDL写的&#xff0c;我不会 当然verilog我也不太会 就这样&#xff0c;随便写吧 co…

element-plus表单组件之自动补全组件el-autocomplete和级联选择器组件el-cascader

el-autocomplete 自动补全组件 自补全组件的功能和可以根据输入过滤的el-select组件有些类似。 fetch-suggestions 根据输入框的输入获取建议的内容&#xff0c;其接受值是一个函数&#xff0c;有2个参数&#xff0c;querystring:输入的内容&#xff0c;callback内置函数&…

数据结构C语言版:顺序表基本操作的实现

参考教材&#xff1a;数据结构C语言版&#xff08;严蔚敏&#xff0c;吴伟民编著&#xff09; 目录 线性表的基本操作&#xff1a; 1&#xff1a;线性表L的初始化(参数用引用) 2&#xff1a;销毁线性表L 3&#xff1a;清空线性表L 4&#xff1a;求线性表L的长度 5&#xf…

比亚迪智驾技术震撼登场!L3级自动驾驶领跑全国,无图导航、夜间挑战轻松应对!

作为新能源汽车领域的翘楚&#xff0c;比亚迪在电池技术与智能驾驶方面都有着卓越的表现。近日&#xff0c;比亚迪凭借其领先的智驾技术&#xff0c;成功入选全国首批L3级自动驾驶上路及行驶试点名单&#xff0c;这无疑将推动智驾技术的普及速度。 你知道吗&#xff1f;比亚迪智…

Java高手的30k之路|面试宝典|熟悉常用开源集合库Guava和ApacheCommonsCollections

Apache Commons Collections Apache Commons Collections 是一个扩展 Java Collections Framework 的开源库&#xff0c;提供了许多实用的集合类和相关工具。 常用的集合类&#xff1a; 1. Bag 接口及其实现 Bag 是一个特殊的集合&#xff0c;允许重复元素&#xff0c;并能…

写作工具:用latex代码插入公式(GPT prompt)

其中所有的公式都直接显示latex代码&#xff0c;不要进行编译&#xff0c;注意公式必须前后有$$&#xff0c;单独的字母或单词不需要用latex&#xff0c;比如i这个字母&#xff1b;如&#xff1a; $ $\Gamma(z) \int_0^\infty t^{z-1}e^{-t}dt\,. $ $ &#xff08;复制粘贴该p…

单目标应用:基于三角拓扑聚合优化算法TTAO的微电网优化(MATLAB代码)

一、微电网模型介绍 微电网多目标优化调度模型简介_vmgpqv-CSDN博客 参考文献&#xff1a; [1]李兴莘,张靖,何宇,等.基于改进粒子群算法的微电网多目标优化调度[J].电力科学与工程, 2021, 37(3):7 二、三角拓扑聚合优化算法求解微电网 2.1算法简介 三角拓扑聚合优化算法&…

如何连接达梦数据库?

连接达梦数据库&#xff08;DM Database&#xff09;可以通过多种方式进行&#xff0c;包括使用 JDBC&#xff08;Java Database Connectivity&#xff09;驱动程序&#xff0c;这是最常见的方式之一。以下是使用 Java 通过 JDBC 连接达梦数据库的详细步骤&#xff1a; 1. 准备…

梦想编织者Luna:COZE从童话绘本到乐章的奇妙转化

前言 Coze是什么&#xff1f; Coze扣子是字节跳动发布的一款AI聊天机器人构建平台&#xff0c;能够快速创建、调试和优化AI聊天机器人的应用程序。只要你有想法&#xff0c;无需有编程经验&#xff0c;都可以用扣子快速、低门槛搭建专属于你的 Chatbot&#xff0c;并一键发布…

002、浅谈MongoDB数据库的优势

1. 灵活的数据模型 MongoDB 的文档存储方式允许你随时更改文档的结构而不需要中断应用程序&#xff0c;特别适合需求变化快的场景。 实例&#xff1a; 电商平台&#xff1a; 在一个电商平台中&#xff0c;不同类别的商品可能有不同的属性。例如&#xff0c;电子产品有保修期&…

gbase8s数据库的逻辑日志、物理日志和两种特殊情形的学习

(一) 日志的介绍 1. 日志的类别 数据库日志主要是分为记录日志、逻辑日志和物理日志。 记录日志&#xff1a;记录日志包括了数据库的报错日志、连接日志、sql执行等信息&#xff0c;这些日志不存储在dbspace上&#xff0c;而是保存在操作系统的文件内逻辑日志和物理日志&…

linux下C语言如何操作文件(二)

上篇文章中,我们简单介绍了file_util.h中定义的各函数,今天我们来讲解如何实现头文件中定义的各函数。首先,在file_util.c中,我们需要引入相应的头文件: #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <unistd.h> #inc…