SpringBoot MVC自动装配原理及MVC拓展

springboot运行原理:https://blog.csdn.net/gdnlnsjd/article/details/121439543
springboot自动装配原理:https://blog.csdn.net/gdnlnsjd/article/details/121441166

我们已经了解了springboot的运行原理和自动装配原理,我们还需要知道一个东西,就是SpringBoot对我们的SpringMVC还做了哪些配置,包括如何扩展,如何定制。

我们从源码和官方文档去分析
官方文档

我们从官方文档中得到下面的解析:

Spring MVC Auto-configuration
// Spring Boot为Spring MVC提供了自动配置,它可以很好地与大多数应用程序一起工作。
Spring Boot provides auto-configuration for Spring MVC that works well with most applications.
// 自动配置在Spring默认设置的基础上添加了以下功能:
The auto-configuration adds the following features on top of Spring’s defaults:
// 包含视图解析器
Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.
// 支持静态资源文件夹的路径,以及webjars
Support for serving static resources, including support for WebJars
// 自动注册了Converter:
// 转换器,这就是我们网页提交数据到后台自动封装成为对象的东西,比如把"1"字符串自动转换为int类型
// Formatter:【格式化器,比如页面给我们了一个2019-8-10,它会给我们自动格式化为Date对象】
Automatic registration of Converter, GenericConverter, and Formatter beans.
// HttpMessageConverters
// SpringMVC用来转换Http请求和响应的的,比如我们要把一个User对象转换为JSON字符串,可以去看官网文档解释;
Support for HttpMessageConverters (covered later in this document).
// 定义错误代码生成规则的
Automatic registration of MessageCodesResolver (covered later in this document).
// 首页定制
Static index.html support.
// 图标定制
Custom Favicon support (covered later in this document).
// 初始化数据绑定器:帮我们把请求数据绑定到JavaBean中!
Automatic use of a ConfigurableWebBindingInitializer bean (covered later in this document).

如果您希望保留Spring Boot MVC功能,并且希望添加其他MVC配置(拦截器、格式化程序、视图控制器和其他功能),则可以添加自己
的@configuration类,类型为webmvcconfiguer,但不添加@EnableWebMvc。如果希望提供
RequestMappingHandlerMapping、RequestMappingHandlerAdapter或ExceptionHandlerExceptionResolver的自定义
实例,则可以声明WebMVCregistrationAdapter实例来提供此类组件。
*/
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.

// 如果您想完全控制Spring MVC,可以添加自己的@Configuration,并用@EnableWebMvc进行注释。
If you want to take complete control of Spring MVC, you can add your own @Configuration annotated with @EnableWebMvc.

我们来仔细对照,看一下它怎么实现的,它告诉我们SpringBoot已经帮我们自动配置好了SpringMVC,然后自动配置了哪些东西呢?


自动配置了ViewResolver,就是我们之前学习的SpringMVC的视图解析器;

即根据方法的返回值取得视图对象(View),然后由视图对象决定如何渲染(转发,重定向)。

我们去看看这里的源码:我们找到 WebMvcAutoConfiguration , 然后搜索ContentNegotiatingViewResolver。找到如下方法!
在这里插入图片描述
我们点到ContentNegotiatingViewResolver中看看这个类
在这里插入图片描述
我们发现它实现了ViewResolver接口,实现了ViewResolver接口的类,我们就可以将其看作视图解析器。

我们再进入这个接口中
在这里插入图片描述
我们发现这个接口中就一个resolveViewName()方法,我们看看ContentNegotiatingViewResolver是如何重写这个方法的

在这里插入图片描述
// getCandidateViews():获取候选的视图对象
//getBestView():选择一个最适合的视图对象,然后把这个对象返回

点进getCandidateViews()看看:
在这里插入图片描述
我们可以看到他是把所有的视图解析器拿来,进for循环,挨个解析,然后将所有候选视图返回

所以得出结论:ContentNegotiatingViewResolver 这个视图解析器就是用来组合所有的视图解析器的

我们再去研究下他的组合逻辑,看到for循环中遍历的属性viewResolvers,看看它是在哪里进行赋值的!
在这里插入图片描述
// 这里它是从beanFactory工具中获取容器中的所有视图解析器


既然它是在容器中去找视图解析器,我们是否可以猜想,我们就可以去实现一个视图解析器了呢?

我们可以自己给容器中去添加一个视图解析器;这个类就会帮我们自动的将它组合进来;我们去实现一下

1、我们在我们的主程序中去写一个视图解析器来试试;
在这里插入图片描述
2、怎么看我们自己写的视图解析器有没有起作用呢?
我们给 DispatcherServlet 中的 doDispatch方法 加个断点进行调试一下,因为所有的请求都会走到这个方法中
在这里插入图片描述
在这里插入图片描述

![在这里插入图片描述](https://img-blog.csdnimg.cn/fb7fd7c3c8d64112891df0234a0cdabb.png

发现我们自己写的视图解析器确实生效了


所以说,我们如果想要使用自己定制化的东西,我们只需要给容器中添加这个组件就好了!剩下的事情SpringBoot就会帮我们做了!
我们再看看我们还能自己定制些什么

转换器和格式化器

找到格式化转换器,我们看看其中时间的格式转换:
在这里插入图片描述

点进去:
在这里插入图片描述
在这里插入图片描述

发现这个属性存在于WebMvcProperties类中,所以我们可以对其进行自定义配置

在这里插入图片描述

其余的就不一一举例了,大家可以下去多研究探讨即可!


扩展使用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.
如果您希望保留Spring Boot MVC功能,并且希望添加其他MVC配置(拦截器、格式化程序、视图控制器和其他功能),则可以添加自己的@configuration类,类型为webmvcconfiguer,但不添加@EnableWebMvc。如果希望提供RequestMappingHandlerMappingRequestMappingHandlerAdapter或ExceptionHandlerExceptionResolver的自定义实例,则可以声明WebMVCregistrationAdapter实例来提供此类组件。

我们要做的就是编写一个@Configuration注解类,并且类型要为WebMvcConfigurer,还不能标注@EnableWebMvc注解;我们去自己写一个;我们新建一个包叫config,写一个类MyMvcConfig,再添加一个addViewControllers()试试;

在这里插入图片描述
我们去浏览器访问一下:
在这里插入图片描述
确实也跳转过来了!所以说,我们要扩展SpringMVC,官方就推荐我们这么去使用(即自己写一个实现webmvcconfiguer接口的类,既保SpringBoot留所有的自动配置,也能用我们扩展的配置!

我们可以去分析一下原理:

1、WebMvcAutoConfiguration 是 SpringMVC的自动配置类,里面有一个类WebMvcAutoConfigurationAdapter
在这里插入图片描述

2、这个类上有一个注解,在做其他自动配置时会导入:@Import(EnableWebMvcConfiguration.class)

3、我们点进EnableWebMvcConfiguration这个类看一下,它继承了一个父类:DelegatingWebMvcConfiguration
在这里插入图片描述

这个父类中有这样一段代码:
在这里插入图片描述

即从IOC容器中获取所有的webmvcConfigurer(包括我们自定义的实现了webmvcConfigurer接口的自定义类),组合到WebMvcConfigurerComposite中

我们可以在这个类中去寻找一个我们刚才自定义类中重写的addViewControllers当做参考,发现它调用了一个
在这里插入图片描述

点进去
在这里插入图片描述
在这里插入图片描述

所以得出结论:所有的WebMvcConfiguration都会被作用,不止Spring自带的配置类,我们自己的配置类当然也会被调用;


那为什么不能加@EnableWebMvc呢?因为加了之后默认的mvc自动配置类就会失效,由我们自定义的类完全控制Spring MVC

在这里插入图片描述
点进@EnableWebMvc看看
在这里插入图片描述
发现它导入了一个DelegatingWebMvcConfiguration类,而这个类继承了WebMvcConfigurationSupport类
在这里插入图片描述
我们再看看WebMvcAutoConfiguration自动配置类生效的条件
在这里插入图片描述
所以如果我们使用了@EnableWebMvc,Ioc容器中就存在了WebMvcConfigurationSupport类,默认的mvc自动配置类就会失效,由我们自定义的类完全控制Spring MVC

但是建议不要这样去做,还是在保留默认配置的情况下,新添WebMvcConfiguration即可(即自定义一个配置类实现WebMvcConfiguration接口,然后在里面添加自定义的配置)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值