可以查看官方文档:https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-spring-mvc-auto-configuration 保持上面的特性,扩展MVC,可以写一个class,加上注解@Configuration和接口WebMvcConfigurer,并且不能加@EnableWebMvc,如果加上@EnableWebMvc,就不是扩展了,而是全面接管。
然后重写接口WebMvcConfigurer的方法
test.html
@Configuration public class MvcConfig implements WebMvcConfigurer { //设置视图跳转 @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/springboot").setViewName("test"); } }其他的类似,重写方法即可:
Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans. 包含ContentNegotiatingViewResolver和BeanNameViewResolver的beans
我们在WebMvcAutoConfiguration类里面找到ContentNegotiatingViewResolver的源码:
@Bean @ConditionalOnBean({ViewResolver.class}) @ConditionalOnMissingBean( name = {"viewResolver"}, value = {ContentNegotiatingViewResolver.class} ) public ContentNegotiatingViewResolver viewResolver(BeanFactory beanFactory) { ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver(); resolver.setContentNegotiationManager((ContentNegotiationManager)beanFactory.getBean(ContentNegotiationManager.class)); resolver.setOrder(-2147483648); return resolver; }再点进类ContentNegotiatingViewResolver,找到和解析视图的类:
public class ContentNegotiatingViewResolver extends WebApplicationObjectSupport implements ViewResolver, Ordered, InitializingBean { ....... ....... ....... @Nullable public View resolveViewName(String viewName, Locale locale) throws Exception { RequestAttributes attrs = RequestContextHolder.getRequestAttributes(); Assert.state(attrs instanceof ServletRequestAttributes, "No current ServletRequestAttributes"); List<MediaType> requestedMediaTypes = this.getMediaTypes(((ServletRequestAttributes)attrs).getRequest()); if (requestedMediaTypes != null) { List<View> candidateViews = this.getCandidateViews(viewName, locale, requestedMediaTypes); View bestView = this.getBestView(candidateViews, requestedMediaTypes, attrs); if (bestView != null) { return bestView; } } String mediaTypeInfo = this.logger.isDebugEnabled() && requestedMediaTypes != null ? " given " + requestedMediaTypes.toString() : ""; if (this.useNotAcceptableStatusCode) { if (this.logger.isDebugEnabled()) { this.logger.debug("Using 406 NOT_ACCEPTABLE" + mediaTypeInfo); } return NOT_ACCEPTABLE_VIEW; } else { this.logger.debug("View remains unresolved" + mediaTypeInfo); return null; } } ....... ....... ....... }里面有句代码:List<View> candidateViews = this.getCandidateViews(viewName, locale, requestedMediaTypes);我们可以点进getCandidateViews方法,看它是怎么Views,通过下图可知是迭代循环,会解析每一个视图,接下我们可以再自定义的MvcConfig中写一个视图解析器放入bean中,最后springboot也会帮我们解析。
测试:
@Configuration public class MvcConfig implements WebMvcConfigurer { @Bean //放到bean中 public ViewResolver myViewResolver(){ return new MyViewResolver(); } //静态内部类,视图解析器需要实现接口ViewResolver public static class MyViewResolver implements ViewResolver{ @Override public View resolveViewName(String s, Locale locale) throws Exception { return null; } } }断点调试:给doDispatch类打上断点:(在DispatcherServlet类找到内部类doDispatch)
可以看到我们自己写的视图解析器: