9、简单功能分析
文章目录
- 1、静态资源访问
- 1.1、静态资源目录
- 1.2、如果静态资源与controller资源重名
- 1.3、改变默认的静态资源路径
- 1.4、修改静态资源访问前缀
- 1.5、webjar
- 2、欢迎页支持
- 3、自定义 Favicon
- 4、静态资源配置原理
- 4.1、与Web开发有关的相关自动配置类
- 4.2、WebMvcAutoConfiguration 注解介绍
- 4.3、WebMvcAutoConfiguration 功能介绍
- 4.4 WebMvcAutoConfigurationAdapter 内部类
- 1、唯一有参构造器
- 2、资源处理的默认规则
- 4.5 EnableWebMvcConfiguration 内部类
- 1、欢迎页的处理规则
- 4.6、favicon
【尚硅谷】SpringBoot2零基础入门教程-讲师:雷丰阳
笔记
路还在继续,梦还在期许
1、静态资源访问
1.1、静态资源目录
默认静态资源放在类路径下: resources 下 /static 或 /public 或 /resources 或 /META-INF/resources 目录下
访问地址: 当前项目根路径/ + 静态资源名
原理: 写静态资源名自动找到静态资源,静态资源映射/**。
spring:# 默认mvc:static-path-pattern: /**
/**的意思是所有文件夹及里面的子文件夹
/*是所有文件夹,不含子文件夹
1.2、如果静态资源与controller资源重名
请求进来,先去找Controller看能不能处理。
不能处理的所有请求又都交给静态资源处理器。
静态资源也找不到则响应404页面
1.3、改变默认的静态资源路径
spring:# 默认mvc:static-path-pattern: /**# 改变默认的静态资源路径resources:static-locations: [classpath:/haha/]
1.4、修改静态资源访问前缀
添加前缀
spring:# 添加前缀mvc:static-path-pattern: /res/**
访问地址:当前项目 + static-path-pattern的值 + 静态资源名 = 静态资源文件夹下找
1.5、webjar
可以自动映射 /webjars/** 下的资源
官网
<dependency><groupId>org.webjars</groupId><artifactId>jquery</artifactId><version>3.5.1</version>
</dependency>
存放路径:META-INF/resources/webjars/jquery/3.5.1/jquery.js
访问地址:http://localhost:8080/webjars/jquery/3.5.1/jquery.js 后面地址要按照依赖里面的包路径
2、欢迎页支持
- 静态资源路径下 放 index.html
- 可以配置静态资源路径
- 但是不可以配置静态资源的访问前缀。否则导致 index.html不能被默认访问
spring:
# mvc:
# static-path-pattern: /res/** 这个会导致welcome page功能失效resources:static-locations: [classpath:/haha/]
- controller能处理/index
3、自定义 Favicon
favicon.ico 放在静态资源目录下,spring boot 会自动将这个名字的图标当成应用的图标。
spring:
# mvc:
# static-path-pattern: /res/** 这个会导致 Favicon 功能失效
4、静态资源配置原理
spring boot 启动时,会默认加载 xxxAutoConfiguration 类(自动配置类),这里从配置类入手查看源码。
4.1、与Web开发有关的相关自动配置类
DispatcherServletAutoConfiguration: 配置SpringNVC中DispatcherServlet
HttpEncodingAutoConfiguration: 配置编解码
MultipartAutoConfiguration: 配置文件上传
ServletWebServerFactoryAutoConfiguration: 配置服务器
WebMvcAutoConfiguration: SpringMVC功能的自动配置类
4.2、WebMvcAutoConfiguration 注解介绍
// 当前类为配置类,组件之间无依赖关系
@Configuration(proxyBeanMethods = false)
// 程序是Servlet应用
@ConditionalOnWebApplication(type = Type.SERVLET)
// 导入Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class 这三个类
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
// 容器中没有 WebMvcConfigurationSupport.class 组件,当前类中配置才生效
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {}
4.3、WebMvcAutoConfiguration 功能介绍
位置:org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
// SpringMVC用于兼容REST风格
@Bean
@ConditionalOnMissingBean(HiddenHttpMethodFilter.class)
@ConditionalOnProperty(prefix = "spring.mvc.hiddenmethod.filter", name = "enabled", matchIfMissing = false)
public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {return new OrderedHiddenHttpMethodFilter();
}// 表单内容过滤器
@Bean
@ConditionalOnMissingBean(FormContentFilter.class)
@ConditionalOnProperty(prefix = "spring.mvc.formcontent.filter", name = "enabled", matchIfMissing = true)
public OrderedFormContentFilter formContentFilter() {return new OrderedFormContentFilter();
}
4.4 WebMvcAutoConfigurationAdapter 内部类
位置:org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration.WebMvcAutoConfigurationAdapter
// Defined as a nested config to ensure WebMvcConfigurer is not read when not
// on the classpath
@Configuration(proxyBeanMethods = false)
@Import(EnableWebMvcConfiguration.class)
// 把配置文件的相关属性与WebMvcProperties=(spring.mvc)、ResourceProperties进行绑定=(spring.resources)
@EnableConfigurationProperties({ WebMvcProperties.class, ResourceProperties.class })
@Order(0)
public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer {}
1、唯一有参构造器
有参构造器所有参数的值都会从容器中确定
形参 | 作用 |
---|---|
ResourceProperties resourceProperties; | 获取和spring.resources绑定的所有的值的对象 |
WebMvcProperties mvcProperties | 获取和spring.mvc绑定的所有的值的对象 |
ListableBeanFactory beanFactory | Spring的beanFactory(spring的容器) |
HttpMessageConverters | 找到所有的HttpMessageConverters |
ResourceHandlerRegistrationCustomizer | 找到 资源处理器的自定义器。重点 |
DispatcherServletPath | DispatcherServlet处理的路径 |
ServletRegistrationBean | 给应用注册Servlet、Filter… |
public WebMvcAutoConfigurationAdapter(ResourceProperties resourceProperties, WebMvcProperties mvcProperties,ListableBeanFactory beanFactory, ObjectProvider<HttpMessageConverters> messageConvertersProvider,ObjectProvider<ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider,ObjectProvider<DispatcherServletPath> dispatcherServletPath,ObjectProvider<ServletRegistrationBean<?>> servletRegistrations) {this.resourceProperties = resourceProperties;this.mvcProperties = mvcProperties;this.beanFactory = beanFactory;this.messageConvertersProvider = messageConvertersProvider;this.resourceHandlerRegistrationCustomizer = resourceHandlerRegistrationCustomizerProvider.getIfAvailable();this.dispatcherServletPath = dispatcherServletPath;this.servletRegistrations = servletRegistrations;
}
2、资源处理的默认规则
添加资源处理器
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {// 拿到与配置文件绑定的属性spring.resources.add-mappings=true(false禁用静态资源路径映射)if (!this.resourceProperties.isAddMappings()) {//true不进入,false进入logger.debug("Default resource handling disabled");return;}// 获取到配置文件中,静态资源的缓存策略,所有的静态资源在浏览器默认存多少秒Duration cachePeriod = this.resourceProperties.getCache().getPeriod();// 注册第一种访问规则:/webjars/**CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();// 在项目中寻找静态资源if (!registry.hasMappingForPattern("/webjars/**")) {customizeResourceHandlerRegistration(registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/").setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));}// 获取配置文件中spring.mvc.static-path-pattern的值,没有配置就使用默认值:/**String staticPathPattern = this.mvcProperties.getStaticPathPattern();// 在项目中寻找默认位置:{ "classpath:/META-INF/resources/","classpath:/resources/", "classpath:/static/", "classpath:/public/" };// 默认的位置也可以修改if (!registry.hasMappingForPattern(staticPathPattern)) {customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern).addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations())).setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));}
}
spring:resources:add-mappings: false #禁用所有静态资源规则cache:period: 1100 # 以秒为单位
4.5 EnableWebMvcConfiguration 内部类
/*** Configuration equivalent to {@code @EnableWebMvc}.*/
@Configuration(proxyBeanMethods = false)
public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware {}
1、欢迎页的处理规则
HandlerMapping:处理器映射,保存了每一个Handler能处理哪些请求。
利用反射向容器中注入WelcomePageHandlerMapping ,作用:寻找谁可以处理欢迎页的映射。
@Bean
public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext,FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(new TemplateAvailabilityProviders(applicationContext), applicationContext, getWelcomePage(),this.mvcProperties.getStaticPathPattern()); // 获取spring.mvc.static-path-pattern 的值welcomePageHandlerMapping.setInterceptors(getInterceptors(mvcConversionService, mvcResourceUrlProvider));welcomePageHandlerMapping.setCorsConfigurations(getCorsConfigurations());return welcomePageHandlerMapping;
}
位置:org.springframework.boot.autoconfigure.web.servlet.WelcomePageHandlerMapping
final class WelcomePageHandlerMapping extends AbstractUrlHandlerMapping {WelcomePageHandlerMapping(TemplateAvailabilityProviders templateAvailabilityProviders,ApplicationContext applicationContext, Optional<Resource> welcomePage, String staticPathPattern) {// 条件:欢迎页存在,并且路径是默认/**if (welcomePage.isPresent() && "/**".equals(staticPathPattern)) {logger.info("Adding welcome page: " + welcomePage.get());setRootViewName("forward:index.html");}else if (welcomeTemplateExists(templateAvailabilityProviders, applicationContext)) {// 调用Controller看谁能处理/indexlogger.info("Adding welcome page template: index");setRootViewName("index");}}
}
4.6、favicon
与代码无关,浏览器默认发送当前项目下的favicon功能,当添加访问静态资源前缀,就会找不到。
相关文章:

9、简单功能分析
文章目录1、静态资源访问1.1、静态资源目录1.2、如果静态资源与controller资源重名1.3、改变默认的静态资源路径1.4、修改静态资源访问前缀1.5、webjar2、欢迎页支持3、自定义 Favicon4、静态资源配置原理4.1、与Web开发有关的相关自动配置类4.2、WebMvcAutoConfiguration 注解…...

如何发送和接收参数?五种参数传递方法
通常情况下,我们可以使用GET或POST来发送请求和数据,但GET和POST两种方法所携带的数据都是比较简单的数据,接下来在我们这个基础上,列举5种比较负责的参数传递方法,并对这些参数如何发送,后台改如何接收做详…...

蓝桥杯C/C++VIP试题每日一练之矩形面积交
💛作者主页:静Yu 🧡简介:CSDN全栈优质创作者、华为云享专家、阿里云社区博客专家,前端知识交流社区创建者 💛社区地址:前端知识交流社区 🧡博主的个人博客:静Yu的个人博客 🧡博主的个人笔记本:前端面试题 个人笔记本只记录前端领域的面试题目,项目总结,面试技…...

Spark大数据处理讲课笔记2.4 IDEA开发词频统计项目
文章目录零、本讲学习目标一、词频统计准备工作(一)启动集群的HDFS与Spark(二)在HDFS上准备单词文件二、本地模式执行Spark程序(一)创建Maven项目(二)添加Spark相关依赖,…...

【ChatGPT 】国内无需注册 openai 即可访问 ChatGPT:ChatGPT Sidebar 浏览器扩展程序的安装与使用
一、前言 问题:国内注册 openai 账号麻烦,新必应有部分人也无法登录成功,存在域名单点登录失败等问题,所以无法真正使用 ChatGPT 解决:大部分人仅需使用 ChatGPT 的搜索功能,无需真正对话,需要…...

使用fetch()异步请求API数据实现汇率转换器
任务8 https://segmentfault.com/a/1190000038998601 https://chinese.freecodecamp.org/news/how-to-master-async-await-with-this-real-world-example/ 跟随上面的指示,理解异步函数的编写,并且实现这个汇率转换器。 第一步:在工作区初始…...

GPT-4“王炸”,10秒钟开发一套Web + APP 系统
10秒钟做出一个网站 一则有关GPT4发布会的视频在网上流传,这则两分钟的视频演示的内容是: 1. 在草稿本上用纸笔画出一个非常粗糙的草图; 2. 拍照告诉 GPT 我们要做一个网站,效果正如图所示,让其生成网站代码࿱…...

Disjoint 集合数据结构或 Union-Find 算法简介
联合查找算法是一种对此类数据结构执行两个有用操作的算法: 查找:确定特定元素在哪个子集中。这可用于确定两个元素是否在同一子集中。联合:将两个子集连接成一个子集。这里首先我们必须检查这两个子集是否属于同一个集合。如果否,…...
uniapp中nvue与vue的区别?
文章目录简介nvue 和 vue 相互通讯方式:nvue注意事项:简介 uni-app是逻辑渲染分离的,渲染层在app端提供了两套排版引擎, 小程序方式的webview渲染和weex方式的原生渲染,两种渲染引入可以自己根据需要选。 vue文件走的…...
带头双向循环链表的实现
1.结构体的创建以及类型重定义 typedef int LTDataType; typedef struct ListNode {LTDataType data;struct ListNode* prev;struct ListNode* next; }LTNode;2.链表的初始化 这个函数用于创建节点,后面还会用到。 LTNode* BuyListNode(LTDataType x) {LTNode* n…...

大屏使用dv-digital-flop定时刷新显示总人数
本文在基础上进行改进,后端使用若依后端IofTV-Screen: 🔥一个基于 vue、datav、Echart 框架的物联网可视化(大屏展示)模板,提供数据动态刷新渲染、屏幕适应、数据滚动配置,内部图表自由替换、Mixins注入等功…...

Java面向对象部分 个人学习记录
注:此博客是个人学习记录,会有错的地方,面向对象部分我可能会画很多图来加深我的理解 不引出了,直接开始 class Dog{String name;int age;String type;public Dog(String name,int age,String type){this.namename;this.ageage;this.typetyp…...

MySQL数据库——对Linux MySQL软件包的一些说明
Linux 操作系统的发行版很多,不同发行版下的 MySQL 版本也是不同的。MySQL 主要支持的 Linux 版本有 Red Hat Enterprise Linux 和 SUSE Linux Enterprise Server。这里主要介绍不同 Linux 发行版下 MySQL 支持的版本。 Linux 操作系统的 MySQL 软件包一般分为以下…...

【JavaEE进阶】——第二节.Spring核心和设计思想
文章目录 前言 一、Spring是什么? 二、什么是容器? 三、什么是IoC? 3.1 初始loC 3.2 举例解释loC 3.3 Spring IoC思想的体现 四、什么是DI? 4.1DI的概念 4.2 Ioc和DI的区别 总结 前言 今天我们将进入到有关spring的认识当中&…...

twitter开源算法(1)For You推荐系统架构
1 Twitter’s Recommendation Algorithm 我们的推荐系统由许多互相关联的服务(services)和工作(jobs)组成,本节这要是聚焦home timeline的for you feed流。 the-algorithm开源地址:https://github.com/twitter/the-algorithm 本篇博客来源&…...
A General Framework for Uncertainty Estimation in Deep Learning源码阅读(二)
接上文 ResNet定义: 代码使用 def ResNet18ADF(noise_variance1e-3, min_variance1e-3):return ResNet(BasicBlock, [2,2,2,2], num_classes10, noise_variance1e-3, min_variance1e-3, initialize_msraFalse)定义模型,其中ResNet定义为: …...

串行通信协议---HART协议
实际应用中,HART协议是仅次于Modbus协议的最接近统一现场总线的标准,主要是在4~20mA电流信号上面叠加数字信号,物理层采用Bell 202标准的FSK技术成功实现模拟信号和数字信号双向同时通信而互不干扰。HART协议规定了传输的物理形式、消息结构、…...
【独家】华为OD机试 - 寻找密码(C 语言解题)
最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为od机试,独家整理 已参加机试人员的实战技巧本期题目:寻找密码 题目 小王在进行游…...

FPGA有哪些优质的带源码的IP开源网站?
这是某乎上的一个问题,我觉得还不错,今天就系统性的总结一下1、fpga4funhttps://www.fpga4fun.com/你能在这个网站上找到什么?您可以找到信息页面,以及使用 FPGA 板构建的 FPGA 项目。注重点:项目。FPGA 项目使用一种称…...

基于模型预测控制(MPC)的微电网调度优化的研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)
升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求ÿ…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...
力扣-35.搜索插入位置
题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...