spring boot springMVC扩展配置实现解析

所属分类: 软件编程 / java 阅读数: 28
收藏 0 赞 0 分享

摘要:

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

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

示例:

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

@Configuration
public 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 代码如下 (写了几个案列方法,其他代码省略。)。

@Configuration
public 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 也就被调用了。

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

更多精彩内容其他人还在看

Springmvc restful配置遇到的小坑

本文是小编给大家带了的Springmvc restful配置遇到的小小坑,小编给大家带来了问题原因及解决办法,非常不错,具有参考借鉴价值,感兴趣的朋友一起看下吧
收藏 0 赞 0 分享

Java中的匿名内部类小结

java内部类分为: 成员内部类、静态嵌套类、方法内部类、匿名内部类。这篇文章主要介绍了Java中的匿名内部类的相关资料,需要的朋友可以参考下
收藏 0 赞 0 分享

Java的云打印Lodop

这篇文章主要介绍了Java的云打印Lodop 的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

Java线程池框架核心代码解析

这篇文章主要针对Java线程池框架核心代码进行详细解析,分析Java线程池框架的实现ThreadPoolExecutor,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

Java 交换两个变量的数值实现方法

下面小编就为大家带来一篇Java 交换两个变量的数值实现方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

全面了解JAVA_BaseDAO数据处理类

下面小编就为大家带来一篇全面了解JAVA_BaseDAO数据处理类。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

java、python、JavaScript以及jquery循环语句的区别

本篇文章主要介绍java、python、JavaScript以及jquery的循环语句的区别,这里整理了它们循环语句语法跟示例,以便大家阅读,更好的区分它们的不同
收藏 0 赞 0 分享

基于JDBC封装的BaseDao(实例代码)

下面小编就为大家带来一篇基于JDBC封装的BaseDao(实例代码)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

简单通用JDBC辅助类封装(实例)

下面小编就为大家带来一篇简单通用JDBC辅助类封装(实例)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

浅谈java线程中生产者与消费者的问题

下面小编就为大家带来一篇浅谈java线程中生产者与消费者的问题。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享
查看更多