spring boot springMVC扩展配置实现解析
摘要:
在springboot中MVC这部分也有默认自动配置,也就是说我们不用做任何配置,那么也是OK的,这个配置类就是WebMvcAutoConfiguration,但是也时候我们想设置自己的springMvc配置怎么办呢。
我们也可以写个自己的配置类,继承WebMvcConfigurer重写需要的配置方法。在springboot早期是继承WebMvcConfigurerAdapter,但是高版已标上注解@Deprecated,注意:在配置类中不要标注:@EnableWebMvc,否则,springboot的配置全部失效,只留自己扩展配置。
示例:
这里已高版为主继承WebMvcConfigurer,WebMvcConfigurer接口中的方法都是默认的方法,可以覆盖,也可以不实现,加一个视图解析配置,解析success请求路劲,返回success页面。如下代码:
@Configuration publicclassMyMvcConfigImplementsWebMvcConfigurer{ @Override publicvoidaddViewControllers(ViewControllerRegistryregistry){ //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}) publicclassWebMvcAutoConfiguration{ ....//省略部分代码 @Configuration @Import({WebMvcAutoConfiguration.EnableWebMvcConfiguration.class})//导入了EnableWebMvcConfiguration这个类addResourceHandlers方法 @EnableConfigurationProperties({WebMvcProperties.class,ResourceProperties.class}) @Order(0) publicstaticclassWebMvcAutoConfigurationAdapterimplementsWebMvcConfigurer,ResourceLoaderAware{ ...//省略部分代码 publicvoidaddResourceHandlers(ResourceHandlerRegistryregistry){//实现WebMvcConfigurer这个类的 if(!this.resourceProperties.isAddMappings()){ logger.debug("Defaultresourcehandlingdisabled"); }else{ DurationcachePeriod=this.resourceProperties.getCache().getPeriod(); CacheControlcacheControl=this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl(); if(!registry.hasMappingForPattern("/webjars/**")){ this.customizeResourceHandlerRegistration(registry.addResourceHandler(newString[]{"/webjars/**"}).addResourceLocations(newString[]{"classpath:/META-INF/resources/webjars/"}).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl)); } StringstaticPathPattern=this.mvcProperties.getStaticPathPattern(); if(!registry.hasMappingForPattern(staticPathPattern)){ this.customizeResourceHandlerRegistration(registry.addResourceHandler(newString[]{staticPathPattern}).addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations())).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl)); } } } }
可以看到,内部类WebMvcAutoConfigurationAdapter标记@Configuration,并导入另一个内部类@Import({WebMvcAutoConfiguration.EnableWebMvcConfiguration.class}),我们看下这个类,如下代码:
@Configuration publicstaticclassEnableWebMvcConfigurationextendsDelegatingWebMvcConfiguration{ privatefinalWebMvcPropertiesmvcProperties; privatefinalListableBeanFactorybeanFactory; privatefinalWebMvcRegistrationsmvcRegistrations; ...//省略 }
重点在它的父类,DelegatingWebMvcConfiguration代码如下(写了几个案列方法,其他代码省略。)。
@Configuration publicclassDelegatingWebMvcConfigurationextendsWebMvcConfigurationSupport{ privatefinalWebMvcConfigurerCompositeconfigurers=newWebMvcConfigurerComposite(); ...//省略 /** *从容器中拿到所有WebMvcConfigurer的实现类。遍历添加到configurers *[requireddescription] *@type{[type]} */ @Autowired(required=false)//自动装配 publicvoidsetConfigurers(Listconfigurers){ if(!CollectionUtils.isEmpty(configurers)){ this.configurers.addWebMvcConfigurers(configurers); } } ...//省略 /** *当调用addResourceHandlers时,调用的成员configurers的addResourceHandlers *[addResourceHandlersdescription] *@param{[type]}ResourceHandlerRegistryregistry[description] */ protectedvoidaddResourceHandlers(ResourceHandlerRegistryregistry){ this.configurers.addResourceHandlers(registry); } ...//省略 }
来看看WebMvcConfigurerComposite的addResourceHandlers的方法做了什么:
classWebMvcConfigurerCompositeimplementsWebMvcConfigurer{ privatefinalListdelegates=newArrayList (); @Override publicvoidaddViewControllers(ViewControllerRegistryregistry){//遍历把所有WebMvcConfigurer的addViewControllers方法调用一遍 for(WebMvcConfigurerdelegate:this.delegates){ delegate.addViewControllers(registry); } } }
看到这里我们知道,不管是springboot中实现的WebMvcConfigurer类,还是我们自己实现WebMvcConfigurer,只要我们把实现类注入到容器中,就会被注入WebMvcConfigurerComposite这个类成员变量delegates中。
而WebMvcConfigurerComposite有是实现了WebMvcConfigurer。当调用WebMvcConfigurer中xxx方法的,就会遍历delegates中所有WebMvcConfigurer的方法xxx。那我们的扩展配置MyMvcConfig也就被调用了。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。