随笔记录-springmvc_ResourceHandlerRegistry+ResourceHttpRequestHandler

环境:springboot-2.7.5

配置文件配置静态资源映射

springboot配置静态资源映射方式是通过 WebMvcAutoConfiguration 实现的

spring:
#  resources:
# 	 # 自springboot 2.5.5之后,该属性已经被废弃,使用spring.web.resources.static-locations代替
#    static-locations: classpath:/static/,classpath:/META-INF/resources/,classpath:/META-INF/resources/webjars/,file:E:/images/
  # 静态资源配置
  mvc:
    # 静态资源访问接口前缀
    static-path-pattern: /static/**
  web:
    resources:
      # 静态资源本地路径
      static-locations: classpath:/static/,classpath:/META-INF/resources/,classpath:/META-INF/resources/webjars/,file:E:/images/

该方式仅支持一种前缀匹配(spring.mvc.static-path-pattern)

自定义静态资源映射

可以继承 WebMvcConfigurationSupport 或者 WebMvcConfigurer 接口。

建议:
a、手动覆盖静态资源,实现 WebMvcConfigurer 接口(前提是比其他实现类后加载,见 OrderComparator#doCompare – @Order值越大越靠后)
b、完全覆盖静态资源,继承 WebMvcConfigurationSupport 类,重写所有资源映射
注意:
a、继承 WebMvcConfigurationSupport 类时,WebMvcAutoConfiguration 配置 和 其他所有实现 WebMvcConfigurer 接口的的配置都失效
b、实现 WebMvcConfigurer 接口时,最好通过 ResourceHandlerRegistry#hasMappingForPattern 方法判断一下,否则存在多个同名前缀,启动会报错 (2023-11-27修正ResourceHandlerRegistry#getHandlerMapping 方法【见图-将配置的静态资源映射转化为Map】,是可以对同名前缀进行覆盖的 —> urlMap是LinkedHashMap,可以不能重复但有序)
c、添加静态映射时,handler名称前面统一加上“/”:如果不加,spring会自动加上【见图-静态资源的handler名称首部加上“/”】,有可能就会导致b中情况urlMap无法覆盖,但在【图-缓存静态资源映射的handler供获取时使用】中判断时就存在了同名的handler(已经加了“/”)导致报错无法启动
有无"/"开头同名静态资源名称导致异常
d、@Order最大值是Integer.MAX_VALUE,而没有该注解,默认也是该值,因此自己项目的 WebMvcConfigurer 实现类可能无法设定在最后,从而实现静态资源覆盖

注: 继承 WebMvcConfigurationSupport 类时,在整合第三方时,一定程度上有可能导致某些未知异常 -- WebMvcConfigurer 接口有很多方法,第三方项目可能是实现该接口来处理的,此时所有该接口的实现类均失效,就有可能导致某些配置没有正确加载。

配置静态资源映射

创建名为resourceHandlerMapping的bean对象
创建一个resourceHandlerMapping的bean对象(SimpleUrlHandlerMapping
通过resourceHandlerMapping方法获取实例
WebMvcConfigurationSupport#resourceHandlerMapping
添加静态资源映射并转化为SimpleUrlHandlerMapping

→添加静态资源映射并转化为 SimpleUrlHandlerMapping ↑

ResourceHandlerRegistryaddResourceHandler 方法添加前缀匹配路径,addResourceLocations 添加本地映射路径。配置之后就保存了一份列表,当获取Mapping时,返回 SimpleUrlHandlerMapping
将配置的静态资源映射转化为Map

→将配置的静态资源映射转化为Map↑

获取bean之后,对bean对象进行初始化过程
初始化bean

→初始化bean↑

初始化方法,就是判断是否 实现 InitializingBean 接口 和 配置initMethod方法名(@Bean的initMethod、xml的init-method属性)
a、实现 InitializingBean 接口,调用afterPropertiesSet方法
b、指定initMethod方法名,反射调用方法
初始化方法前后,通过 BeanPostProcessor 的applyBeanPostProcessorsBeforeInitialization和applyBeanPostProcessorsAfterInitialization方法分别前后处理

AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization(处理一些列BeanPostProcessor)
ApplicationContextAwareProcessor#postProcessBeforeInitialization
ApplicationContextAwareProcessor#invokeAwareInterfaces
ApplicationObjectSupport#setApplicationContext
ApplicationObjectSupport#initApplicationContext(org.springframework.context.ApplicationContext)
SimpleUrlHandlerMapping#initApplicationContext
SimpleUrlHandlerMapping#registerHandlers
处理静态资源的handler名称

→静态资源的handler名称首部加上“/”↑

AbstractUrlHandlerMapping#registerHandler(java.lang.String, java.lang.Object)
保存静态资源映射的handler

→缓存静态资源映射的handler供获取时使用↑

配置跨域

CorsRegistry 跨域支持配置

访问静态资源过程

获取handler

DispatcherServlet#doDispatch
DispatcherServlet#getHandler
获取handler
AbstractHandlerMapping#getHandler
AbstractUrlHandlerMapping#getHandlerInternal
AbstractUrlHandlerMapping#lookupHandler(java.lang.String, javax.servlet.http.HttpServletRequest)
获取匹配的前缀路径

→获取匹配的前缀路径↑

获取合适的handler

→获取目标handler↑

添加跨域配置

→目标handler添加跨域配置↑

准备执行handler

→准备执行handler↑

通过handler解析路径

DispatcherServlet#doDispatch
HttpRequestHandlerAdapter#handle
ResourceHttpRequestHandler#handleRequest
PathResourceResolver#getResource(java.lang.String, javax.servlet.http.HttpServletRequest, java.util.List<? extends org.springframework.core.io.Resource>)
解析文件资源
FileUrlResource#createRelative
UrlResource#createRelativeURL
new java.net.URL#URL(java.net.URL, java.lang.String)
StreamHandler#parseURL
处理资源

org.springframework.http.converter.AbstractHttpMessageConverter#write
响应内容

备注:
java.net.URLStreamHandler#parseURL解析url时,file协议的路径,会截取开头到最后一个“/”位置
file路径截取


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
springboot:是一个基于Java开发的框架,简化了Spring应用的初始化配置和部署过程。它提供了一套开发规范和约定,帮助开发人员快速搭建高效稳定的应用程序。 mybatis-plus:是基于MyBatis的增强工具,提供了一些便捷的CRUD操作方法和代码生成功能,简化了数据库操作的开发工作。它能够轻松集成到SpringBoot应用中,提高开发效率。 springmvc:是一种基于MVC设计模式的Web框架,用于构建Web应用程序。它能够从URL中解析请求参数,并将请求分发给对应的Controller进行处理。SpringMVC提供了一套灵活的配置和注解方式,支持RESTful风格的API开发。 shiro:是一种用于身份验证和授权的框架,可以集成到SpringBoot应用中。它提供了一套简单易用的API,可以处理用户认证、角色授权、会话管理等安全相关的功能。Shiro还支持集成其他认证方式,如LDAP、OAuth等。 redis:是一种开源的内存数据库,采用键值对存储数据。Redis具有高性能、高并发和持久化等特点,常用于缓存、消息队列和分布式锁等场景。在企业级报表后台管理系统中,可以使用Redis来进行缓存数据,提高系统的响应速度和性能。 企业级报表后台管理系统:是一种用于统一管理和生成报表的系统。它通常包括用户权限管理、报表设计、报表生成、数据分析等功能。使用SpringBoot、MyBatis-Plus、SpringMVC、Shiro和Redis等技术,可以快速搭建一个可靠、高效的报表管理系统,满足企业对数据分析和决策的需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值