【Spring Boot】装配扩展SpringMVC

    科技2022-07-10  111

    文章目录

    前言1.视图跳转2.视图解析器


    前言

    可以查看官方文档:https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-spring-mvc-auto-configuration 保持上面的特性,扩展MVC,可以写一个class,加上注解@Configuration和接口WebMvcConfigurer,并且不能加@EnableWebMvc,如果加上@EnableWebMvc,就不是扩展了,而是全面接管。

    然后重写接口WebMvcConfigurer的方法

    1.视图跳转

    test.html

    @Configuration public class MvcConfig implements WebMvcConfigurer { //设置视图跳转 @Override public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/springboot").setViewName("test"); } }

    其他的类似,重写方法即可:

    2.视图解析器

    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)

    可以看到我们自己写的视图解析器:

    Processed: 0.080, SQL: 8