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

SpringBoot——MVC原理

优质博文:IT-BLOG-CN

一、SpringMVC自动配置

SpringMVC auto-configurationSpringBoot自动配置好了SpringMVC。以下是SpringBootSpringMVC的默认配置:[WebMvcAutoConfiguration]
【1】包括ContentNegotiatingViewResolverBeanNameViewResolver如下:

@Bean
@ConditionalOnBean({ViewResolver.class})
@ConditionalOnMissingBean(name = {"viewResolver"},value = {ContentNegotiatingViewResolver.class}
)
//存在于 WebMvcAutoConfiguration.java
public ContentNegotiatingViewResolver viewResolver(BeanFactory beanFactory) {ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();resolver.setContentNegotiationManager((ContentNegotiationManager)beanFactory.getBean(ContentNegotiationManager.class));resolver.setOrder(-2147483648);return resolver;
}//进入ContentNegotiatingViewResolver对象,查找解析视图的方法resolveViewName()
public View resolveViewName(String viewName, Locale locale) throws Exception {RequestAttributes attrs = RequestContextHolder.getRequestAttributes();Assert.state(attrs instanceof ServletRequestAttributes, "No current ServletRequestAttributes");List<MediaType> requestedMediaTypes = this.getMediaTypes(((ServletRequestAttributes)attrs).getRequest());if(requestedMediaTypes != null) {//获取候选的视图对象List<View> candidateViews = this.getCandidateViews(viewName, locale, requestedMediaTypes);//选择最适合的视图对象View bestView = this.getBestView(candidateViews, requestedMediaTypes, attrs);if(bestView != null) {return bestView;}
}//进入上面的getCandidateViews()方法,查看获取的视图解析器,发现SpringBoot是将所有的视图解析器获取到viewResolvers,挨个遍历获取。
private List<View> getCandidateViews(String viewName, Locale locale, List<MediaType> requestedMediaTypes) throws Exception {List<View> candidateViews = new ArrayList();Iterator var5 = this.viewResolvers.iterator();while(var5.hasNext()) {

【2】自动配置了ViewResolver(视图解析器:根据方法的返回值得到视图对象(View),视图对象决定如何渲染(转发?重定向?))
【3】ContentNegotiatingViewResolver:组合所有的视图解析器的;

//进入ContentNegotiatingViewResolver发现初始化视图解析器的时候,是从容器中BeanFactoryUtils获取所有的视图解析器。
protected void initServletContext(ServletContext servletContext) {Collection<ViewResolver> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(this.getApplicationContext(), ViewResolver.class).values();if(this.viewResolvers == null) {

【4】如何定制:我们可以自己给容器中添加一个视图解析器;自动的将其组合进来;

 @Bean@ConditionalOnProperty(prefix = "spring.mvc", name = "date‐format")//在文件中配置日期格式化的规则public Formatter<Date> dateFormatter() {        return new DateFormatter(this.mvcProperties.getDateFormat());//日期格式化组件            } //举个栗子如下:
//可以自定义一个视图解析器,放入容器,springboot就会自动识别,继承viewreserve
@Bean
public MyView myView(){return new MyView();
}
//需要实现ViewResolver接口
private static class MyView implements ViewResolver{@Overridepublic View resolveViewName(String s, Locale locale) throws Exception {return null;}
}

【5】服务对静态资源的支持,静态资源文件夹路径,webjars等。静态首页访问,自定义favicon.ico 图标文件的支持。
【6】自动注册了of Converter,GenericConverter,Formatter beans
 ○ Converter:转换器; public String hello(User user):类型转换使用ConverterStringint等等。
 ○ Formatter 格式化器; 2017.12.17===Date,源码如下:可以看到格式可以通过spring.mvc.date-format调整。

@Bean
@ConditionalOnProperty(prefix = "spring.mvc",name = {"date-format"}
)
public Formatter<Date> dateFormatter() {return new DateFormatter(this.mvcProperties.getDateFormat());
}

 ○ 自己添加的格式化器转换器,我们只需要放在容器中即可,上面代码块有演示。
【7】支持HttpMessageConverters
 ○ HttpMessageConverterSpringMVC用来转换Http请求和响应的;UserJson方式写出去;
 ○ HttpMessageConverters是从容器中确定;获取所有的HttpMessageConverter
 ○ 自己给容器中添加HttpMessageConverter,只需要将自己的组件注册容器中[@Bean,@Component]
【8】自动注册MessageCodesResolver,定义错误代码生成规则。自动使用ConfigurableWebBindingInitializer类;

protected ConfigurableWebBindingInitializer getConfigurableWebBindingInitializer() {return (ConfigurableWebBindingInitializer)this.beanFactory.getBean(ConfigurableWebBindingInitializer.class);
}

它是从容器中获取ConfigurableWebBindingInitializer的,从而可知,我们可以配置一个ConfigurableWebBindingInitializer来替换默认的(添加到容器),如果没有配置会初始化一个Web数据绑定器:

//初始化Web数据绑定器,作用就是将请求数据绑定到JavaBean中,参数等,涉及数据转换等等
protected ConfigurableWebBindingInitializer getConfigurableWebBindingInitializer() {ConfigurableWebBindingInitializer initializer = new ConfigurableWebBindingInitializer();initializer.setConversionService(this.mvcConversionService());initializer.setValidator(this.mvcValidator());initializer.setMessageCodesResolver(this.getMessageCodesResolver());return initializer;
}

【9】org.springframework.boot.autoconfigure.webweb的所有自动场景;上面能够得到的主要思想就是:如何修改Springboot的默认配置:
 1)、在自动配置很多组件的时候,先看容器中有木有用户自己配置的(@Bean,@Component)如果有就是用用户配置的,如果没有就是用自动配置的,因为底层使用了@ConditionalOnMiss注解来判断,容器中是否已经存在此类配置。
 2)、如果有些组件可以配置多个,比如视图解析器(ViewResolver)将用户配置的和自己默认的组合起来。

扩展 SpringMVC: 官方解释:If you want to keep Spring Boot MVC features and you want to add additional MVC configuration (interceptors, formatters, view controllers, and other features), you can add your own @Configuration class of type WebMvcConfigurer but without @EnableWebMvc. If you wish to provide custom instances of RequestMappingHandlerMapping, RequestMappingHandlerAdapter, or ExceptionHandlerExceptionResolver, you can declare a WebMvcRegistrationsAdapter instance to provide such components.

【1】根据我们之前的配置xml来进行扩展:

<mvc:view‐controller path="/hello" view‐name="success"/>
<mvc:interceptors><mvc:interceptor><mvc:mapping path="/hello"/><bean></bean></mvc:interceptor>
</mvc:interceptors>

【2】SpringBoot编写一个配置类@Configuration,继承WebMvcConfigurerAdapter类型,不能标注@EnableWebMvc。 继承抽象类既保留了所有的自动配置,也能用我们扩展的配置;

//使用WebMvcConfigurerAdapter可以来扩展SpringMVC的功能
@Configuration
public class MyMvcConfig extends WebMvcConfigurerAdapter {@Overridepublic void addViewControllers(ViewControllerRegistry registry) {// super.addViewControllers(registry);//浏览器发送 /yintong 请求来到 success ,视图映射,当没有业务逻辑的时候就比较方便registry.addViewController("/yintong").setViewName("success");}
}

原理:
【1】WebMvcAutoConfigurationSpringMVC的自动配置类;
【2】在做其他自动配置时会导入;@Import(EnableWebMvcConfiguration.class)

@Configuration
public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration {    private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite();//从容器中获取所有的WebMvcConfigurer    @Autowired(required = false)public void setConfigurers(List<WebMvcConfigurer> configurers) {if (!CollectionUtils.isEmpty(configurers)) {this.configurers.addWebMvcConfigurers(configurers);//一个参考实现;将所有的WebMvcConfigurer相关配置都来一起调用;      @Override    public void addViewControllers(ViewControllerRegistry registry) {for (WebMvcConfigurer delegate : this.delegates) {delegate.addViewControllers(registry);}}}
}

【3】容器中所有的WebMvcConfigurer都会一起起作用;
【4】我们的配置类也会被调用;
【5】效果:SpringMVC的自动配置和我们的扩展配置都会起作用;

二、全面接管SpringMVC

让所有SpringMVC的自动配置都失效。使用我们需要的配置,需要在配置类中添加 @EnableWebMvc即可。非常不推荐,不然使用SpringBoot开发干嘛,哈哈。

//使用WebMvcConfigurerAdapter可以来扩展SpringMVC的功能 
@EnableWebMvc 
@Configuration 
public class MyMvcConfig extends WebMvcConfigurerAdapter {     @Override     public void addViewControllers(ViewControllerRegistry registry) {// super.addViewControllers(registry);         //浏览器发送 /atguigu 请求来到 success                 registry.addViewController("/atguigu").setViewName("success");     } 
}

原理: 为什么@EnableWebMvc自动配置就失效了?

【1】@EnableWebMvc的核心组合注解:

@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {

【2】我们打开上面导入的DelegatingWebMvcConfiguration类,会发现其继承了WebMvcConfigurationSupport

@Configuration
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {

【3】我们看下SpringBoot自动配置的文件,发现如下:@ConditionalOnMissingBean(WebMvcConfigurationSupport.class),可知当容器中存在WebMvcConfigurationSupport类时,就不会导入自动配置的类了,第二步导入的就是这个类。

@Configuration
@ConditionalOnWebApplication
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class,
WebMvcConfigurerAdapter.class })        
//容器中没有这个组件的时候,这个自动配置类才生效
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class,
ValidationAutoConfiguration.class })        
public class WebMvcAutoConfiguration {

【4】@EnableWebMvcWebMvcConfigurationSupport组件导入进来;
【5】导入的WebMvcConfigurationSupport只是SpringMVC最基本的功能;

结论:SpringBoot中会有非常多的xxxConfigurer帮助我们进行扩展配置。同时,在SpringBoot中也会有很多的xxxCustomizer帮助我们进行定制配置。

相关文章:

SpringBoot——MVC原理

优质博文&#xff1a;IT-BLOG-CN 一、SpringMVC自动配置 SpringMVC auto-configuration&#xff1a;SpringBoot自动配置好了SpringMVC。以下是SpringBoot对SpringMVC的默认配置&#xff1a;[WebMvcAutoConfiguration] 【1】包括ContentNegotiatingViewResolver和BeanNameView…...

[Linux] shell条件语句和if语句

一、条件语句 1.1 测试 test 测试文件的表达式是否成立 格式&#xff1a;test 条件表达式 [ 条件表达式 ] 选项作用-d测试是否为目录-e测试目录或文件是否存在-a测试目录或文件是否存在-f测试是否为文件-r测试当前用户是否有权限读取-w测试当前用户是否有权限写入-x测试当前…...

【陈老板赠书活动 - 18期】-如何成为架构师这几本书推荐给你

陈老老老板&#x1f9b8; &#x1f468;‍&#x1f4bb;本文专栏&#xff1a;赠书活动专栏&#xff08;为大家争取的福利&#xff0c;免费送书&#xff09; &#x1f468;‍&#x1f4bb;本文简述&#xff1a;生活就像海洋,只有意志坚强的人,才能到达彼岸。 &#x1f468;‍&am…...

chrome 插件 Mobile simulator

谷歌浏览器插件Mobile simulator v3.8.2.0-2023-4-27&#xff08;做屏幕适应的前端工具&#xff09;-&#xff08;Chrome插件&#xff09;谷歌浏览器插件网 百度网盘&#xff1a;https://pan.baidu.com/s/1xVyny8CtlMjSchhTIlfRAA 提取码&#xff1a;cj5c...

JavaScript框架 Angular、React、Vue.js 的全栈解决方案比较

在 Web 开发领域&#xff0c;JavaScript 提供大量技术栈可供选择。其中最典型的三套组合&#xff0c;分别是 MERN、MEAN 和 MEVN。前端框架&#xff08;React、Angular 和 Vue&#xff09;进行简化比较。 MERN 技术栈详解 MERN 技术栈包含四大具体组件&#xff1a; MongoDB&am…...

【Vue】核心特性(响应式)

响应式&#xff1a; 数据变化&#xff0c;视图自动更新 接下来使用一个例子来体现一下什么是响应式 案例一&#xff1a; 访问数据&#xff0c;视图自动更新 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><…...

ESP32 http 请求

目录 参考教程1.使用的http连接2.使用Vscode-IDF创建http_request例程3.修改http_request_example_main.c函数4.已经获取到响应的数据 参考教程 ESP-IDF HTTP获取网络时间 1.使用的http连接 http://api.m.taobao.com/rest/api3.do?apimtop.common.getTimestamp请求可以得到…...

【C++】拷贝构造函数,析构函数详解!

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …...

qml ParticleSystem3D使用介绍

在 Qt Quick 3D 中,ParticleSystem3D 是用来创建和控制3D粒子系统的元素。粒子系统是图形编程中用于模拟液体、烟雾、火、星空等现象的技术,它通过生成大量小粒子来模拟这些效果。ParticleSystem3D 提供了一个框架,允许开发者定义粒子的各种属性,如生命周期、速度、颜色、大…...

集团投融资大数据平台解决方案

一、项目背景 项目为集团型公司大数据平台项目&#xff0c;整个项目周期约为6个月&#xff0c;整体呈现了对外的数据大屏驾驶仓和对内的看板报表&#xff0c;减少了客户内部数据上报和报表制作的重复工作量&#xff0c;为集团数据决策奠定基础。 二、项目目标 战略层&#xff…...

深信服技术认证“SCSA-S”划重点:渗透测试工具使用

为帮助大家更加系统化的学习网络安全知识&#xff0c;尽快通过深信服安全服务认证工程师认证&#xff0c;深信服推出“SCSA-S认证备考秘笈”共十期内容&#xff0c;“考试重点”内容框架&#xff0c;帮助大家快速get重点知识~ 划重点来啦 深信服安全服务认证工程师&#xff08;…...

CCFCSP试题编号:201803-2试题名称:碰撞的小球

一、题目描述 二、思路 1.首先妾身分析这个题目&#xff0c;想要解题&#xff0c;得得解决2个问题。 1&#xff09;判断小球到达端点或碰撞然后改变方向&#xff1b; 2&#xff09;每时刻都要改变位置 两个问题都比较好解决&#xff0c;1&#xff09;只要简单判断坐标&…...

《安富莱嵌入式周报》第327期:Cortex-A7所有外设单片机玩法LL/HAL库全面上线,分享三款GUI, PX5 RTOS推出网络协议栈,小米Vela开源

周报汇总地址&#xff1a;嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Powered by Discuz! 1、2023 Hackaday大赛胸牌开源 Vectorscope-main.zip (66.83MB) GitHub - Hack-a-Day/Vectorscope: Vectorscope badg…...

面试官:【js多维数组扁平化去重并排序】

文章目录 前言方法一方法二方法三方法四总结后言 前言 hello world欢迎来到前端的新世界 &#x1f61c;当前文章系列专栏&#xff1a;JavaScript &#x1f431;‍&#x1f453;博主在前端领域还有很多知识和技术需要掌握&#xff0c;正在不断努力填补技术短板。(如果出现错误&a…...

C#编程题分享(3)

n的阶乘问题 输⼊整数n&#xff0c;输出n的阶乘。 int n Convert.ToInt32(Console.ReadLine()); int jiecheng 1; for (int i 1; i < n 1; i) {jiecheng * i; // 1 * 2 * 3 * .....} Console.WriteLine("{0}的阶乘是&#xff1a;{1}", n, jiecheng); q^n次…...

Redis下载和安装(Windows系统)

通过 GitHub 来下载 Windows 版 Redis 安装包,下载地址&#xff1a;点击前往。 打开上述的下载链接&#xff0c;Redis 支持 32 位和 64 位的 Window 系统&#xff0c;大家根据个人情况自行下载&#xff0c;如图 1 所示&#xff1a; 下载完成后&#xff0c;打开相应的文件夹&a…...

MySQL数据库:开源且强大的关系型数据库管理系统

大家好&#xff0c;我是咕噜-凯撒&#xff0c;数据在当今信息化时代的重要性不可忽视。作为企业和组织的重要资产&#xff0c;数据的管理和存储变得至关重要&#xff0c;MySQL作为一种关系型数据库管理系统&#xff0c;具有非常多的优势&#xff0c;下面简单的探讨一下MySQL数据…...

如何在AD的PCB板做矩形槽孔以及如何倒圆弧角

Altium Designer 22下载安装教程-CSDN博客 如何在AD上创建完整的项目-CSDN博客 开始前&#xff0c;请先安装后AD&#xff0c;并创建好项目。 目录 1. 如何在AD的PCB板做矩形槽孔 2. 如何在AD的PCB板倒圆弧角 1. 如何在AD的PCB板做矩形槽孔 首先&#xff0c;我们进入上面创…...

SpringMVC日志追踪笔记整理

新建logback-spring.xml <?xml version"1.0" encoding"UTF-8"?> <configuration><property name"PATH" value"./log/business"></property><appender name"STDOUT" class"ch.qos.logback…...

UML建模图文详解教程06——顺序图

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl本文参考资料&#xff1a;《UML面向对象分析、建模与设计&#xff08;第2版&#xff09;》吕云翔&#xff0c;赵天宇 著 顺序图概述 顺序图(sequence diagram&#xff0c;也…...

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

基于FPGA的PID算法学习———实现PID比例控制算法

基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容&#xff1a;参考网站&#xff1a; PID算法控制 PID即&#xff1a;Proportional&#xff08;比例&#xff09;、Integral&#xff08;积分&…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享

文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的&#xff0c;根据Excel列的需求预估的工时直接打骨折&#xff0c;不要问我为什么&#xff0c;主要…...

【2025年】解决Burpsuite抓不到https包的问题

环境&#xff1a;windows11 burpsuite:2025.5 在抓取https网站时&#xff0c;burpsuite抓取不到https数据包&#xff0c;只显示&#xff1a; 解决该问题只需如下三个步骤&#xff1a; 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj&#xff0c;再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

大数据学习(132)-HIve数据分析

​​​​&#x1f34b;&#x1f34b;大数据学习&#x1f34b;&#x1f34b; &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版

7种色调职场工作汇报PPT&#xff0c;橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版&#xff1a;职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...

Python 训练营打卡 Day 47

注意力热力图可视化 在day 46代码的基础上&#xff0c;对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...

区块链技术概述

区块链技术是一种去中心化、分布式账本技术&#xff0c;通过密码学、共识机制和智能合约等核心组件&#xff0c;实现数据不可篡改、透明可追溯的系统。 一、核心技术 1. 去中心化 特点&#xff1a;数据存储在网络中的多个节点&#xff08;计算机&#xff09;&#xff0c;而非…...