WebMvcConfigurationSupport 和 WebMvcConfigurer 区别你知道吗

简介: WebMvcConfigurationSupport 和 WebMvcConfigurer 的使用过程中你是否踩坑了它们的区别是什么快来看看吧

👳我亲爱的各位大佬们好

♨️本篇文章记录的为WebMvcConfigurationSupport 和 WebMvcConfigurer相关内容,适合在学Java的小白,帮助新手快速上手,也适合复习中,面试中的大佬🙉🙉🙉。
♨️如果文章有什么需要改进的地方还请大佬不吝赐教❤️🧡💛
👨‍🔧 个人主页 : 阿千弟

@[toc]

版本原因

在Spring Boot 1.5版本都是靠重写WebMvcConfigurerAdapter的方法来添加自定义拦截器,消息转换器等。SpringBoot 2.0 后,该类被标记为@Deprecated(弃用)。

在Spring Boot 2.0后用自己的的配置类继承WebMvcConfigurerAdapter时,idea会提示这个类已经过时了。

通常情况下我们会采用下面两种代替方案:

  • 实现WebMvcConfigurer
  • 继承WebMvcConfigurationSupport

在这里插入图片描述

WebMvcConfigurer

为什么WebMvcConfigurer实现要加@EnableWebMvc

  @EnableWebMvc注解类上导入了DelegatingWebMvcConfiguration类,该类是WebMvcConfigurationSupport的子类,该类除了实例化WebMvcConfigurationSupport实例以外,另一个作用就是收集BeanFactory中所有WebMvcConfigurer的实现,汇集到WebMvcConfigurerComposite中,在WebMvcConfigurationSupport实例化过程中会分别调用这些实现,将相应的实例传入这些实现中,供开发者在此基础上添加自定义的配置。这也就是在WebMvcConfigurerAdapter子类上要加@EnableWebMvc的原因,因为要先实例化WebMvcConfigurationSupport

注意:springboot下不需要添加@EnableWebMvc

对于springboot来讲,继承WebMvcConfigure无需再加@EnableWebMvc注解,因为springboot已经实例化了WebMvcConfigurationSupport,如果添加该注解,默认的WebMvcConfigurationSupport配置类是不会生效的,会以用户自定义的为主,一般建议还是不覆盖默认比较好。同时,继承WebMvcConfigurationSupport后,springboot的WebMvc自动配置失效(有可能导致视图解析器无法正常工作)。

### 为什么可以存在多个WebMvcConfigurer的实现?
   一般来讲一个应用中一个WebMvcConfigurer的已经足够,设计成收集多个是不是有些多余?从springboot的autoconfigure机制来看并不多余,反而更灵活,比如我要写一个mybatis的AutoConfiguration和JPA的AutoConfiguration,我就可以在不同的AutoConfiguration里面定义一个WebMvcConfigurer的实现,里面只配置与mybatis或JPA相关的配置,这样需要那个启用那个,不需要人工通过注释代码来转换mybatis和JPA,
### 接口说明
public interface WebMvcConfigurer {
   
   

    void configurePathMatch(PathMatchConfigurer var1);

    void configureContentNegotiation(ContentNegotiationConfigurer var1);

    void configureAsyncSupport(AsyncSupportConfigurer var1);

    void configureDefaultServletHandling(DefaultServletHandlerConfigurer var1);

    void addFormatters(FormatterRegistry var1);

    void addInterceptors(InterceptorRegistry var1);

    void addResourceHandlers(ResourceHandlerRegistry var1);

    void addCorsMappings(CorsRegistry var1);

    void addViewControllers(ViewControllerRegistry var1);

    void configureViewResolvers(ViewResolverRegistry var1);

    void addArgumentResolvers(List<HandlerMethodArgumentResolver> var1);

    void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> var1);

    void configureMessageConverters(List<HttpMessageConverter<?>> var1);

    void extendMessageConverters(List<HttpMessageConverter<?>> var1);

    void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> var1);

    void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> var1);

    Validator getValidator();

    MessageCodesResolver getMessageCodesResolver();
}

常用的方法API

因为现在多用的是前后端分离的项目, 所以前后端不分离的部分方法不再多做阐述

// 这个方法用来注册拦截器,我们自己写好的拦截器需要通过这里添加注册才能生效
void addInterceptors(InterceptorRegistry var1);
/* 视图跳转控制器 */
void addViewControllers(ViewControllerRegistry registry);
// 这个方法是用来配置静态资源的,比如html,js,css,等等
void addResourceHandlers(ResourceHandlerRegistry registry);
/* 默认静态资源处理器 */
void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer);
/* 这里配置视图解析器*/
void configureViewResolvers(ViewResolverRegistry registry);
/* 配置内容裁决的一些选项*/
void configureContentNegotiation(ContentNegotiationConfigurer configurer);
/** 解决跨域问题 **/
public void addCorsMappings(CorsRegistry registry) ;
//拓展mvc框架的消息转换器
void extendMessageConverters(List<HttpMessageConverter<?>> var1);

addInterceptors:拦截器

@Autowired
    private LoginInterceptor loginInterceptor;
    // 这个方法用来注册拦截器,我们自己写好的拦截器需要通过这里添加注册才能生效
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
   
   
        // addPathPatterns("/**") 表示拦截所有的请求,
        // excludePathPatterns("/login", "/register") 表示除了登陆与注册之外,因为登陆注册不需要登陆也可以访问
        registry.addInterceptor(loginInterceptor)
                .addPathPatterns("/**").
                excludePathPatterns("/employee/login", "/employee/register","/backend/**","/front/**");
    }

addViewControllers:页面跳转, 比如登录跳转或错误页面跳转

以前写SpringMVC的时候,如果需要访问一个页面,必须要写Controller类,然后再写一个方法跳转到页面,感觉好麻烦,其实重写WebMvcConfigurer中的addViewControllers方法即可达到效果了

  @Override
    public void addViewControllers(ViewControllerRegistry registry) {
   
   
        registry.addViewController("/toLogin").setViewName("login");

        registry.addViewController("/403").setViewName("/403");
        registry.addViewController("/404").setViewName("/404");
    }

值的指出的是,在这里重写addViewControllers方法,并不会覆盖WebMvcAutoConfiguration(Springboot自动配置)中的addViewControllers(在此方法中,Spring Boot将“/”映射至index.html),这也就意味着自己的配置和Spring Boot的自动配置同时有效,这也是我们推荐添加自己的MVC配置的方式。

extendMessageConverters : 消息转换器

//拓展mvc框架的消息转换器
    @Autowired
    private CustomObjectMapper customObjectMapper;
    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
   
   

        //创建消息转换器对象
        MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();
        //设置消息转换器,底层使用jackson将Java对象转成json
        messageConverter.setObjectMapper(customObjectMapper);
        //将我们自定义的消息转换器追加到mvc框架的集合转换器中
        converters.add(0, messageConverter);
    }

在这里插入图片描述

WebMvcConfigurationSupport

WebMvcConfigurationSupport中那些子类可以重写的空方法在WebMvcConfigurer都有,这说明WebMvcConfigurer只是WebMvcConfigurationSupport的一个扩展类,它并没有扩展新功能,只是为让用户更方便安全的添加自定义配置,为什么说是安全呢?

因为如果直接继承WebMvcConfigurationSupport,那么用户可以重写默认的配置,如果对原理不是很清楚地开发者不小心重写了默认的配置,springmvc可能相关功能就无法生效,是一种不安全的行为。

继承WebMvcConfigurationSupport时发现会造成一些问题

先看一下WebMvc自动配置类WebMvcAutoConfiguration的定义:

在这里插入图片描述

@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)

看到这行可以明白,原来SpringBoot做了这个限制, 只有当WebMvcConfigurationSupport类不存在的时候才会生效WebMvc自动化配置,WebMvc自动配置类中不仅定义了classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/等路径的映射,还定义了配置文件spring.mvc开头的配置信息等。

继承WebMvcConfigurationSupport会发现Spring Boot的WebMvc自动配置失效(WebMvcAutoConfiguration自动化配置)
如果想要使用自动配置生效,又要按自己的需要重写某些方法,比如增加拦截器。那么将配置类继承WebMvcConfigurationSupport改为实现WebMvcConfigurer接口即可。

在这里插入图片描述

如果这篇【文章】有帮助到你💖,希望可以给我点个赞👍,创作不易,如果有对Java后端或者对spring感兴趣的朋友,请多多关注💖💖💖
👨‍🔧 个人主页 : 阿千弟

目录
相关文章
|
监控 Java Spring
Spring Boot 拦截器(Interceptor)详解
本文介绍Spring Boot拦截器的原理与使用,涵盖自定义拦截器创建、注册配置、执行顺序及典型应用场景,助力提升系统安全性与可维护性。(238字)
1485 1
|
9月前
|
JSON Java 数据格式
Spring Boot中的全局异常处理
本文介绍了Spring Boot项目中如何实现全局异常处理。通过@ControllerAdvice和@ExceptionHandler统一捕获系统异常与自定义业务异常,结合统一JSON返回结构,避免代码耦合,提升可维护性。同时封装异常枚举类,实现异常信息集中管理,确保返回给前端的错误提示友好、规范,广泛适用于前后端分离及微服务架构。
|
8月前
|
IDE 安全 开发工具
告别频繁切换分支!用 Git Worktrees + Claude Code 构建高效并行开发流
本文介绍 Git Worktrees 与 Claude Code 的高效组合:用 Worktrees 创建多分支独立工作区,零拷贝、秒级切换;Claude 则在隔离环境中安全试错、并行开发。告别 stash 焦虑,实现真正并行开发流。(239字)
4377 1
|
缓存 NoSQL Java
Spring Boot 3 整合 Spring Cache 与 Redis 缓存实战
Spring Boot 3 整合 Spring Cache 与 Redis 缓存实战
|
canal 缓存 NoSQL
Redis缓存与数据库如何保证一致性?同步删除+延时双删+异步监听+多重保障方案
根据对一致性的要求程度,提出多种解决方案:同步删除、同步删除+可靠消息、延时双删、异步监听+可靠消息、多重保障方案
Redis缓存与数据库如何保证一致性?同步删除+延时双删+异步监听+多重保障方案
|
Java
错误:has been compiled by a more recent version of the Java Runtime (class file version 56.0)
错误:has been compiled by a more recent version of the Java Runtime (class file version 56.0)
7409 0
|
监控 安全 Java
什么是AOP?如何与Spring Boot一起使用?
什么是AOP?如何与Spring Boot一起使用?
1439 5
|
消息中间件 编解码 网络协议
Netty从入门到精通:高性能网络编程的进阶之路
【11月更文挑战第17天】Netty是一个基于Java NIO(Non-blocking I/O)的高性能、异步事件驱动的网络应用框架。使用Netty,开发者可以快速、高效地开发可扩展的网络服务器和客户端程序。本文将带您从Netty的背景、业务场景、功能点、解决问题的关键、底层原理实现,到编写一个详细的Java示例,全面了解Netty,帮助您从入门到精通。
3209 0
|
Java Android开发
IDEA设置项目编码格式【修改为GBK 或 UTF-8】
这篇文章介绍了在IntelliJ IDEA中如何设置项目编码格式,包括将项目编码修改为GBK或UTF-8的详细步骤和图解。
25036 12
IDEA设置项目编码格式【修改为GBK 或 UTF-8】

热门文章

最新文章