当前位置: 首页 > news >正文

spring通过RequestContextHolder获取HttpServletRequest对象

1.获取HttpServletRequest对象方法:
    public static HttpServletRequest getRequest() {ServletRequestAttributes attributes = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());assert attributes != null;return attributes.getRequest();}
2.RequestContextHolder是一个持有请求和响应上下文的对象,其持有如下两个ThreadLocal对象用于保存当前请求的上下文对象
    private static final ThreadLocal<RequestAttributes> requestAttributesHolder = new NamedThreadLocal("Request attributes");private static final ThreadLocal<RequestAttributes> inheritableRequestAttributesHolder = new NamedInheritableThreadLocal("Request context");

RequestContextHolder类中全部是静态方法,可以直接使用设置属性、清空属性相关方法;

3.RequestContextFilter过滤器用户设置和销毁当前上下文对象
public class RequestContextFilter extends OncePerRequestFilter {...protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {ServletRequestAttributes attributes = new ServletRequestAttributes(request, response);//初始化this.initContextHolders(request, attributes);try {filterChain.doFilter(request, response);} finally {//销毁this.resetContextHolders();if (this.logger.isTraceEnabled()) {this.logger.trace("Cleared thread-bound request context: " + request);}attributes.requestCompleted();}}private void initContextHolders(HttpServletRequest request, ServletRequestAttributes requestAttributes) {LocaleContextHolder.setLocale(request.getLocale(), this.threadContextInheritable);//初始化上下文属性RequestContextHolder.setRequestAttributes(requestAttributes, this.threadContextInheritable);if (this.logger.isTraceEnabled()) {this.logger.trace("Bound request context to thread: " + request);}}private void resetContextHolders() {LocaleContextHolder.resetLocaleContext();//销毁上下文属性RequestContextHolder.resetRequestAttributes();}
}
4.RequestContextFilter过滤器对象实例化
  • RequestContextFilter对象有一个子类OrderedRequestContextFilter
public class OrderedRequestContextFilter extends RequestContextFilter implements OrderedFilter {private int order = -105;public OrderedRequestContextFilter() {}public int getOrder() {return this.order;}public void setOrder(int order) {this.order = order;}
}
  • RequestContextFilter过滤器的实例化实际上是通过OrderedRequestContextFilter对象实例化实现

OrderedRequestContextFilter过滤器源码:

public class OrderedRequestContextFilter extends RequestContextFilter implements OrderedFilter {//过滤器执行优先级  private int order = -105;public OrderedRequestContextFilter() {}public int getOrder() {return this.order;}public void setOrder(int order) {this.order = order;}
}

OrderedRequestContextFilter过滤器实例化:

		@Bean@ConditionalOnMissingBean({ RequestContextListener.class, RequestContextFilter.class })@ConditionalOnMissingFilterBean(RequestContextFilter.class)public static RequestContextFilter requestContextFilter() {return new OrderedRequestContextFilter();}

org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration.WebMvcAutoConfigurationAdapter#requestContextFilter

5.OncePerRequestFilter过滤器

OncePerRequestFilter是Spring框架中一个抽象类,用于确保过滤器在每次请求中只通过一次,这是通过重写doFilterInternal方法来实现的,而不是通过重写doFilter方法。OncePerRequestFilter通过Spring的过滤器链管理来确保这一点。

6.RequestContextFilter在整个servlet容器中的顺序
  • CharacterEncodingFilter -2147483648
  • WebStaFilterRegistrationBean -2147483647
  • FormContentFilter -9900
  • RequestContextFilter(OrderedRequestContextFilter) -105

过滤器的顺序排序是在org.springframework.boot.web.servlet.ServletContextInitializerBeans#ServletContextInitializerBeans中进行:

    @SafeVarargspublic ServletContextInitializerBeans(ListableBeanFactory beanFactory, Class<? extends ServletContextInitializer>... initializerTypes) {this.initializerTypes = initializerTypes.length != 0 ? Arrays.asList(initializerTypes) : Collections.singletonList(ServletContextInitializer.class);this.addServletContextInitializerBeans(beanFactory);this.addAdaptableBeans(beanFactory);//对过滤器进行排序this.sortedList = this.initializers.values().stream().flatMap((value) -> {return value.stream().sorted(AnnotationAwareOrderComparator.INSTANCE);}).toList();this.logMappings(this.initializers);}

开源 SDK:https://github.com/mingyang66/spring-parent

http://www.lryc.cn/news/499110.html

相关文章:

  • STM32编码器接口及编码器测速模板代码
  • qt QNetworkAccessManager详解
  • 部署 Vue 前端项目到 Linux
  • 数据分析:探索数据背后的秘密与挑战
  • 文本域设置高度 加上文字限制并show出来:
  • 深入浅出:Gin框架-简介与API开发入门
  • MySQL各种锁详解
  • 海外的bug-hunters,不一样的403bypass
  • React 组件中 State 的定义、使用及正确更新方式
  • Jenkins 的HTTP Request 插件为什么不能配置Basic认证了
  • 8 Bellman Ford算法SPFA
  • nginx不允许静态文件被post请求显示405 not allowed
  • 【c++笔试强训】(第三十二篇)
  • shell脚本实战案例
  • OpenCV-图像阈值
  • lvgl9 Line(lv_line) 控件使用指南
  • 区块链概念 Web 3.0 实操
  • 【人工智能】大数据平台技术及应用
  • Scala的模式匹配(7)
  • 使用 MATLAB 绘制三维散点图:根据坐标和距离映射点的颜色和大小
  • 数仓技术hive与oracle对比(五)
  • 金融数学在股市交易中的具体应用
  • Spring6:1 概述
  • Python Selenium 各浏览器驱动下载与配置使用(详细流程)
  • C语言期末考试——重点考点
  • mongo开启慢日志及常用命令行操作、数据备份
  • Mybatis-Plus的主要API
  • 2023 年“泰迪杯”数据分析技能赛B 题企业财务数据分析与造假识别
  • 【SpringMVC】参数传递 重定向与转发 REST风格
  • 性能测试需求分析(超详细总结)