Spring Boot 与 Spring MVC
根据SpringBoot 官方文档中的资料 ,可以看出SpringBoot和SpringMVC的关系。
本章节提到的官文文档地址如下:
<https://docs.spring.io/spring-boot/docs/2.1.7.RELEASE/reference/html/boot-features-developing-web-applications.html#boot-features-spring-mvc-auto-configuration
1. Spring Boot 中Spring MVC 自动配置
官方文档中的原文如下:
Spring Boot provides auto-configuration for Spring MVC that works well with most applications.
The auto-configuration adds the following features on top of Spring’s defaults:
-
Inclusion of
ContentNegotiatingViewResolver
andBeanNameViewResolver
beans.- 自动配置viewResolver (视图解析器:根据方法返回的值获得视图对象 )
ContentNegotiatingViewResolver
: 组合所有的试图解析器- 自定义:可以自己给容器中添加视图解析器 ,自动为我们组合起来
-
Support for serving static resources, including support for WebJars (covered later in this document)).
- 支持静态文件夹路径,也包括webjars
-
Automatic registration of
Converter
,GenericConverter
, andFormatter
beans.-
自动注册
Converter
,GenericConverter
, andFormatter
Converter
: 转换器 (类型转换)Formatter
: 格式化器 例如:日期格式转换
-
//添加转换器和格式化器
@Override
public void addFormatters(FormatterRegistry registry) {
for (Converter<?, ?> converter : getBeansOfType(Converter.class)) {
registry.addConverter(converter);
}
for (GenericConverter converter : getBeansOfType(GenericConverter.class)) {
registry.addConverter(converter);
}
for (Formatter<?> formatter : getBeansOfType(Formatter.class)) {
registry.addFormatter(formatter);
}
}
-
Support for
HttpMessageConverters
(covered later in this document).HttpMessageConverters
: Spring MVC用来转换Http请求和响应HttpMessageConverters
: 从容器中拿到所有的HttpMessageConverter
-
Automatic registration of
MessageCodesResolver
(covered later in this document).- 错误代码
-
Static
index.html
support.- 支持静态首页
-
Custom
Favicon
support (covered later in this document).- 支持自定义小图标
-
Automatic use of a
ConfigurableWebBindingInitializer
bean (covered later in this document).
2. Spring MVC的拓展
默认SpringBoot 对 Spring MVC 的自动配置 对应开发不够的 ,还需要拓展SpringMVc的配置 。
以下是SpringBoot的文档对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.
主要关键点
- 编写一个配置类,需要加上
@@Configuration
注解, - 需要是
WebMvcConfigurer
类,继承这个interface - 不能有
@EnableWebMvc
原理
根据Spring MVC 的配置类是 WebMvcAutoConfiguration.class
中的方法WebMvcAutoConfigurationAdapter.class
,其有注解@Import(EnableWebMvcConfiguration.class)
/**
* Configuration equivalent to {@code @EnableWebMvc}.
*/
@Configuration
public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration
@Configuration
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
private final List<WebMvcConfigurer> delegates = new ArrayList();
//其中一段
public void addWebMvcConfigurers(List<WebMvcConfigurer> configurers) {
if (!CollectionUtils.isEmpty(configurers)) {
this.delegates.addAll(configurers);
}
}
根据以上DelegatingWebMvcConfiguration.class
中一部分代码可以知道,我们的配置类继承WebMvcConfigurer
实现的configurer
也会被全添加进List,在WebMvcAutoConfiguration.class
中加载,这就是我们写的配置类可以和自动配置类一起起作用的原因。
3. 全面接管SpringMVC
根据SpringBoot的官方文档还可以知道,SpringBoot是准许我们全面接管SpringMVC的,就像SSM使用方式一样
以下是官方文档的原文:
If you want to take complete control of Spring MVC, you can add your own @Configuration
annotated with @EnableWebMvc
.
如果我们需要完全的控制Spring MVC ,我需要在我们自己的配置类上添加@Configuration
和@EnableWebMvc
.
原理
为什么自动配置会失效?
-
@EnableWebMvc
的核心@Import({DelegatingWebMvcConfiguration.class}) public @interface EnableWebMvc
-
其中导入
DelegatingWebMvcConfiguration.class
@Configuration public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport { private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite
-
查看SpringMVC的自动配置类
WebMvcAutoConfiguration.class
的注解@Configuration @ConditionalOnWebApplication(type = Type.SERVLET) @ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class }) @ConditionalOnMissingBean(WebMvcConfigurationSupport.class) @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10) @AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class }) public class WebMvcAutoConfiguration
其中有一个
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
,当WebMvcConfigurationSupport.class
不存在才加载配置类,当我们的配置类加上@EnableWebMvc
就会导入DelegatingWebMvcConfiguration.class
而它有继承了WebMvcConfigurationSupport
这时候容器中已经存在,就不会加载SpringBoot的SpringMVC自动配置类。