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也就被调用了。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。