5.10 MVC自动配置原理 Spring MVC Auto-configuration
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 and BeanNameViewResolver beans.
视图解析器
Support for serving static resources, including support for WebJars (covered )).
支持静态资源文件夹的路径,以及webjars
Automatic registration of Converter, GenericConverter, and Formatter beans.
Converter转换器:网页提交数据到后台自动封装成为对象,比如把"1"字符串自动转换为int类型
Formatter格式化器:比如页面返回一个2019-8-10,可以自动格式化为Date对象
Support for HttpMessageConverters (covered ).
SpringMVC用来转换Http请求和响应的的
比如我们要把一个User对象转换为JSON字符串
Automatic registration of MessageCodesResolver (covered ).
定义错误代码生成规则
Static index.html support.
首页定制
Custom Favicon support (covered ).
图标定制
Automatic use of a ConfigurableWebBindingInitializer bean (covered ).
/初始化数据绑定器:把请求数据绑定到JavaBean中
If you want to keep those Spring Boot MVC customizations and make more (interceptors, formatters, view controllers, and other features), you can add your own @Configuration class of type WebMvcConfigurer but without@EnableWebMvc.
If you want to provide custom instances of RequestMappingHandlerMapping, RequestMappingHandlerAdapter, or ExceptionHandlerExceptionResolver, and still keep the Spring Boot MVC customizations, you can declare a bean of type WebMvcRegistrations and use it to provide custom instances of those components.
If you want to take complete control of Spring MVC, you can add your own @Configuration annotated with @EnableWebMvc, or alternatively add your own @Configuration-annotated DelegatingWebMvcConfiguration as described in the Javadoc of @EnableWebMvc.
ViewResolver 视图解析器
进入WebMvcAutoConfiguration,这是webmvc的配置类,有viewResolver的相关配置
@Bean @ConditionalOnBean(ViewResolver.class) @ConditionalOnMissingBean(name = "viewResolver", value = ContentNegotiatingViewResolver.class) public ContentNegotiatingViewResolver viewResolver(BeanFactory beanFactory) { ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver(); resolver.setContentNegotiationManager(beanFactory.getBean(ContentNegotiationManager.class)); // ContentNegotiatingViewResolver uses all the other view resolvers to locate // a view so it should have a high precedence // ContentNegotiatingViewResolver使用所有其他视图解析器来定位视图,因此它应该具有较高的优先 resolver.setOrder(Ordered.HIGHEST_PRECEDENCE); return resolver; } ContentNegotiatingViewResolver获得最高优先级
进入ContentNegotiatingViewResolver类查看
public class ContentNegotiatingViewResolver extends WebApplicationObjectSupport implements ViewResolver, Ordered, InitializingBean {}可知其实现了ViewResolver接口,再看看这个接口吧
public interface ViewResolver { /** * Resolve the given view by name. */ @Nullable View resolveViewName(String viewName, Locale locale) throws Exception; }此接口的核心方法是resolveViewName,使用我去看看ContentNegotiatingViewResolver类如何实现这个方法
查看ContentNegotiatingViewResolver类的resolveViewName方法
看看如何获取候选视图的,看看getCandidateViews方法
是从viewResolvers属性拿到的,看看这个属性如何初始化
把所有的视图解析器从BeanFactory找出来,放进viewResolvers属性
我们自己写一个ViewResolver,注册成bean应该就可以了
// 扩展webmvc配置 @Configuration public class MyMvcConfig implements WebMvcConfigurer { // 将自定义的视图解析器装配 @Bean public ViewResolver myViewResolver() { return new MyViewResolver(); } // 自定义一个视图解析器 public static class MyViewResolver implements ViewResolver { @Override public View resolveViewName(String viewName, Locale locale) throws Exception { return null; } } }
调试看看