1.建议
在了解SpringBoot中SpringMVC自动配置原理之前,请先熟悉SpringBoot自动配置原理,这样再来看SpringMVC自动配置原理会简单得多,https://blog.csdn.net/qq_36625757/article/details/83929287这篇博客有详细介绍SpringBoot自动配置原理,欢迎查阅。
2.SpringMVC自动配置原理
1.https://docs.spring.io/spring-boot/docs/2.0.5.RELEASE/reference/htmlsingle/#boot-features-developing-web-applications在SpringBoot的官方文档中有介绍SpringMVC自动配置原理
2.Inclusion of ContentNegotiatingViewResolver
and BeanNameViewResolver
beans.首先SpringBoot自动配置了 ContentNegotiatingViewResolver
及BeanNameViewResolver
,即ViewResolver(视图解析器),根据方法返回值得到视图对象(view),视图对象决定如何渲染(转发或重定向.....),我们进入到WebMvcAutoConfiguration中,这里有通过@Bean向容器中添加一个ContentNegotiatingViewResolver组件
进入到ContentNegotiatingViewResolver中,看它是如何解析视图的
通过getCandidateViews(viewName, locale, requestedMediaTypes);获得候选视图,进入其中
发现是在循环所有的视图解析器,依次解析,所有WebMvcAutoConfiguration这个视图解析器就是在组合所有视图解析器,如果我们添加了自己的视图解析器,WebMvcAutoConfiguration就会将添加的视图解析器组合进来。
3.Support for serving static resources, including support for WebJars (covered later in this document)).静态资源文件夹及webjars
4.Automatic registration of Converter
, GenericConverter
, and Formatter
beans.,自动注册了Converter,GenericConverter,Formatter
Converter:转换器,页面提交文本类型的数据,经过转换器转为对象中的类型,例如:Integer,boolean等......
Formatter:格式化器,将页面提交的数据转为对应的格式,例如:2018-07-01----->Date
源码中可以看出,从beanFactory获得类型为Converter,GenericConverter,Formatter的组件添加到格式化注册中心中,所有我们自己也可以添加格式化器和控制器到容器中
5.Support for HttpMessageConverters
(covered later in this document).配置HttpMessageConverters
功能,HttpMessageConverters
即消息转换器,是SpringMVC中转换Http请求及响应的,例如:将User对象转换为Json返回
WebMvcAutoConfigurationAdapter就只有一个有参构造器,所以在创建WebMvcAutoConfigurationAdapter对象时,就会将HttpMessageConverters传入,即HttpMessageConverters是从容器中确定的,进入到HttpMessageConverters中发现,他也是通过有参构造器从容器中获得HttpMessageConverter
所有我们也可以将自己的HttpMessageConverter添加到容器中,官方文档也有介绍
6.Automatic registration of MessageCodesResolver
(covered later in this document).定义错误代码生成规则
7.Static index.html
support.静态首页访问
8.Custom Favicon
support (covered later in this document),favicon.ico
9.Automatic use of a ConfigurableWebBindingInitializer
bean (covered later in this document).也是通过beanFactory获得,所以我们自己也可以配置一个ConfigurableWebBindingInitializer
Tina及到容器中
如果beanFactory中不存在,就通过父类获取,通过注释可以知道他是初始化web数据绑定器的,就是将请求数据绑定在controller的对象中
当然,SpringMVC的自动配置还有很多,在spring-boot-autoconfigure-2.0.6.RELEASE.jar的org.springframework.boot.autoconfigure.web包下还有很多的自动配置类
3.扩展SpringMVC
1.编写一个配置类,这个配置类的类型为WebMvcConfigurer,并且不能标注@EnableWebMvc,既保留原有配置,也加入了我们自己的配置
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
//使用WebMvcConfigurer扩展MVC功能
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
//浏览器发送/peng请求也来到success页面
registry.addViewController("/peng").setViewName("success");
}
}
原理,来到WebMvcAutoConfiguration中,这个会SpringMVC的自动配置类
发现其中有一个内部类,也是实现类WebMvcConfigurer,在类头上有加上@Import(EnableWebMvcConfiguration.class),即在做其他自动配置是会导入EnableWebMvcConfiguration,进入到EnableWebMvcConfiguration及其父类中
父类中通过@Autowired(required = false)从容器中获得所有的WebMvcConfigurer,在之后的其他方法中通过获得所有的WebMvcConfigurer,循环调用方法(以addViewControllers为例),所以我们自己配置的及SpringBoot配置的WebMvcConfigurer都会一起起作用
4.全面接管SpringMVC
即SpringBoot对SpringMVC配置就不需要了,所有都是我们自己配置,只需要在配置类上加一个@EnableWebMvc注解(不推荐使用)
那么,为啥加一个@EnableWebMvc自动配置就失效了呢?进入其中,发现导入一个DelegatingWebMvcConfiguration
进入到DelegatingWebMvcConfiguration,发现他是WebMvcConfigurationSupport的子类
但在WebMvcAutoConfiguration中明确指出,当容器中不存在WebMvcConfigurationSupport的时候,这个配置才生效
也就是EnableWebMvc导入了WebMvcConfigurationSupport导入进来了,所以SpringBoot对SpringMVC的自动配置类WebMvcAutoConfiguration就失效了,WebMvcConfigurationSupport只是导入了SpringMVC最基本的配置
5.如何修改SpringMVC自动配置
1.SpringBoot在自动配置很多组件时,都会先看容器中有没有用户自己配置的相关组件,如果有就用用户自己配置的,如果没有就自动配置,如果有些组件可以有多个,就会将用户配置的和它自己默认配置的组合起来(例如:ViewResolver)
2.在SpringBoot中会有很多的xxxConfigurer,帮助我们进行扩展配置,所以要留心xxxConfigurer