spring mvc 自动配置
spring boot 启动时会对 spring mvc 做自动配置,默认的配置功能在 org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
中进行了说明。有以下功能:
-
自动注册视图解析器
ContentNegotiatingViewResolver
和BeanNameViewResolver
-
ContentNegotiatingViewResolver
:组合容器中不同ViewResovler BeanNameViewResolver
:根据返回的视图名称去找对应的视图,比如controller中方法返回的视图名称。-
如何自定义一个视图解析器?
可以给容器中添加一个视图解析器,spring boot会自动的将其组合进来@Configuration public class MyViewConfig { @Bean public ViewResolver myView() { return new MyViewResolver(); } private class MyViewResolver implements ViewResolver { @Nullable @Override public View resolveViewName(String viewName, Locale locale) throws Exception { System.out.println("----------------> my view resolver"); return null; } } }
通过在
DispatcherServlet
类中的doDispatch
方法上断点可以查看容器中已经注入了我们自定义的视图解析器:
-
- 支持对静态资源
-
自动注册
Converter
,GenericConverter
和Formatter
-
Converter
和GenericConverter
: 对象参数转换器,把页面提交的文本参数转换为对象属性 -
Formatter
:日期格式化器
-
- 支持
HttpMessageConverters
: spring mvc 中用来转换 http 请求和响应的。比如可以把一个对象转化为 json 格式的 - 自动注册
MessageCodesResolver
: 定义错误代码响应规则的,默认规则可参考DefaultMessageCodesResolver
类 - 支持静态欢迎首页
index.html
- 支持自定义 favicon 图标
- 自动使用
ConfigurableWebBindingInitializer
: 初始化WebDataBinder
数据绑定器
扩展 spring mvc
有时候我需要保持保持 spring boot 对 spring mvc 的支持,同时会要求使用 spring mvc 的其他功能,比如拦截器功能,需要怎么办呢?
- 我们的做法是给容器中添加一个自己的配置类(
@Configuration
),配置类的类型是WebMvcConfigurer
,同时配置类不能被@EnableWebMvc
注解注释。
/**
* 扩展 spring mvc 功能
*/
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/success").setViewName("success");
}
}
全面控制 spring mvc
spring boot 对 spring mvc 的自动配置功能全部失效,spring mvc 的原始的功能都能够使用。需要我们做的是自定义的 spring mvc 配置类上添加注解 @EnableWebMvc
即可。
@Configuration
@EnableWebMvc
public class MyMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/success").setViewName("success");
}
}
- 为什么
@EnableWebMvc
注解会实现此功能呢?其原理如下:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {
}
可以看到@EnableWebMvc
注解实现是导入了配置类DelegatingWebMvcConfiguration
@Configuration
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
}
而该配置类继承了WebMvcConfigurationSupport
,此时我们并没有发现什么特别之处,当你再观察 spring mvc 的配置类WebMvcAutoConfiguration
时,发现该配置类中导入了WebMvcConfigurationSupport
@Configuration
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
//容器中没有这个组件的时候,spring mvc的自动配置类才生效
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class,
TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {
}
@EnableWebMvc
将WebMvcConfigurationSupport
组件导入到容器中,而WebMvcConfigurationSupport
只是支持 spring mvc 的最基本功能
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。