spring boot springMVC扩展配置实现解析

时间:2021-05-19

摘要:

在spring boot中 MVC这部分也有默认自动配置,也就是说我们不用做任何配置,那么也是OK的,这个配置类就是 WebMvcAutoConfiguration,但是也时候我们想设置自己的springMvc配置怎么办呢 。

我们也可以写个自己的配置类,继承 WebMvcConfigurer 重写需要的配置方法 。在spring boot 早期是继承WebMvcConfigurerAdapter ,但是高版已标上注解@Deprecated,注意:在配置类中不要标注:@EnableWebMvc,否则,spring boot的配置全部失效,只留自己扩展配置。

示例:

这里已高版为主 继承WebMvcConfigurer,WebMvcConfigurer 接口中的方法都是默认的方法,可以覆盖,也可以不实现 ,加一个视图解析配置 ,解析success请求路劲,返回success页面。如下代码:

@Configurationpublic class MyMvcConfig Implements WebMvcConfigurer { @Override public void addViewControllers(ViewControllerRegistry registry) { // super.addViewControllers(registry); //浏览器发送 /success请求来到 success registry.addViewController("/success").setViewName("success"); }}

代码浅析:

1.首先我们来看看WebMvcAutoConfiguration这个配置类,这个配置了有首页的默认路劲,还有一些静态资源路劲,而这些方法在它的一个内部类中,如下代码(删除了部分代码):

@Configuration@ConditionalOnWebApplication( type = Type.SERVLET)@ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class})@ConditionalOnMissingBean({WebMvcConfigurationSupport.class})@AutoConfigureOrder(-2147483638)@AutoConfigureAfter({DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class})public class WebMvcAutoConfiguration { ....//省略部分代码 @Configuration @Import({WebMvcAutoConfiguration.EnableWebMvcConfiguration.class}) // 导入了EnableWebMvcConfiguration这个类 addResourceHandlers方法 @EnableConfigurationProperties({WebMvcProperties.class, ResourceProperties.class}) @Order(0) public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer, ResourceLoaderAware {       ...//省略部分代码 public void addResourceHandlers(ResourceHandlerRegistry registry) {//实现WebMvcConfigurer 这个类的 if(!this.resourceProperties.isAddMappings()) { logger.debug("Default resource handling disabled"); } else { Duration cachePeriod = this.resourceProperties.getCache().getPeriod(); CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl(); if(!registry.hasMappingForPattern("/webjars/**")) { this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{"/webjars/**"}).addResourceLocations(new String[]{"classpath:/META-INF/resources/webjars/"}).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl)); } String staticPathPattern = this.mvcProperties.getStaticPathPattern(); if(!registry.hasMappingForPattern(staticPathPattern)) { this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{staticPathPattern}).addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations())).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl)); } } }}

可以看到,内部类 WebMvcAutoConfigurationAdapter 标记 @Configuration,并导入另一个内部类 @Import({WebMvcAutoConfiguration.EnableWebMvcConfiguration.class}),我们看下这个类,如下代码:

@Configuration public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration { private final WebMvcProperties mvcProperties; private final ListableBeanFactory beanFactory; private final WebMvcRegistrations mvcRegistrations;     ...// 省略}

重点在它的父类, DelegatingWebMvcConfiguration 代码如下 (写了几个案列方法,其他代码省略。)。

@Configurationpublic class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport { private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite(); ...//省略 /** * 从容器中拿到所有 WebMvcConfigurer 的实现类。遍历添加到 configurers * [required description] * @type {[type]} */ @Autowired( required = false ) // 自动装配 public void setConfigurers(List<WebMvcConfigurer> configurers) { if(!CollectionUtils.isEmpty(configurers)) { this.configurers.addWebMvcConfigurers(configurers); } } ...//省略 /** * 当调用addResourceHandlers 时 ,调用的 成员configurers的 addResourceHandlers * [addResourceHandlers description] * @param {[type]} ResourceHandlerRegistry registry [description] */ protected void addResourceHandlers(ResourceHandlerRegistry registry) { this.configurers.addResourceHandlers(registry); } ...//省略}

来看看 WebMvcConfigurerComposite 的 addResourceHandlers的方法做了什么 :

class WebMvcConfigurerComposite implements WebMvcConfigurer { private final List<WebMvcConfigurer> delegates = new ArrayList<WebMvcConfigurer>(); @Override public void addViewControllers(ViewControllerRegistry registry) { // 遍历 把 所有WebMvcConfigurer的 addViewControllers方法调用一遍 for (WebMvcConfigurer delegate : this.delegates) { delegate.addViewControllers(registry); } }}

看到这里我们知道,不管是spring boot中实现的 WebMvcConfigurer 类,还是我们自己实现 WebMvcConfigurer ,只要我们把实现类注入到容器中,就会被 注入 WebMvcConfigurerComposite 这个类成员变量 delegates中。

而 WebMvcConfigurerComposite 有是实现了 WebMvcConfigurer 。当调用 WebMvcConfigurer中 xxx方法的,就会遍历 delegates 中所有 WebMvcConfigurer 的方法xxx 。那我们的扩展配置MyMvcConfig 也就被调用了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。

相关文章