持续原创输出,点击上方蓝字关注我

目录

  • 前言
  • Spring Boot 版本
  • 如何扩展MVC?
  • 如何自定义一个拦截器?
  • 什么都不配置为什么依然能运行MVC相关的功能?
  • 如何全面接管MVC?【不推荐】
  • 为什么@EnableWebMvc一个注解就能够全面接管MVC?
  • Spring Boot相关资料
  • 总结

前言

自从用了Spring Boot是否有一个感觉,以前MVC的配置都很少用到了,比如视图解析器,拦截器,过滤器等等,这也正是Spring Boot好处之一。

但是往往Spring Boot提供默认的配置不一定适合实际的需求,因此需要能够定制MVC的相关功能,这篇文章就介绍一下如何扩展和全面接管MVC。

Spring Boot 版本

本文基于的Spring Boot的版本是2.3.4.RELEASE

如何扩展MVC?

在这里需要声明一个前提:配置类上没有标注@EnableWebMvc并且没有任何一个配置类继承了WebMvcConfigurationSupport。至于具体原因,下文会详细解释。

扩展MVC其实很简单,只需要以下步骤

  1. 创建一个MVC的配置类,并且标注@Configuration注解。
  2. 实现WebMvcConfigurer这个接口,并且实现需要的方法。

WebMvcConfigurer这个接口中定义了MVC相关的各种组件,比如拦截器,视图解析器等等的定制方法,需要定制什么功能,只需要实现即可。

在Spring Boot之前的版本还可以继承一个抽象类WebMvcConfigurerAdapter,不过在2.3.4.RELEASE这个版本中被废弃了,如下:

@Deprecated
public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer {}

举个栗子:现在要添加一个拦截器,使其在Spring Boot中生效,此时就可以在MVC的配置类重写addInterceptors()方法,如下:

/**
* MVC扩展的配置类,实现WebMvcConfigurer接口
*/
@Configuration
public class WebConfig implements WebMvcConfigurer { @Autowired
private RepeatSubmitInterceptor repeatSubmitInterceptor; /**
* 重写addInterceptors方法,注入自定义的拦截器
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(repeatSubmitInterceptor).excludePathPatterns("/error");
}
}

操作很简单,除了拦截器,还可以定制视图解析,资源映射处理器等等相关的功能,和Spring MVC很类似,只不过Spring MVC是在XML文件中配置,Spring Boot是在配置类中配置而已。

什么都不配置为什么依然能运行MVC相关的功能?

早期的SSM架构中想要搭建一个MVC其实挺复杂的,需要配置视图解析器,资源映射处理器,DispatcherServlet等等才能正常运行,但是为什么Spring Boot仅仅是添加一个WEB模块依赖即能正常运行呢?依赖如下:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

其实这已经涉及到了Spring Boot高级的知识点了,在这里就简单的说一下,Spring Boot的每一个starter都会有一个自动配置类,什么是自动配置类呢?自动配置类就是在Spring Boot项目启动的时候会自动加载的类,能够在启动期间就配置一些默认的配置WEB模块的自动配置类是WebMvcAutoConfiguration

WebMvcAutoConfiguration这个配置类中还含有如下一个子配置类WebMvcAutoConfigurationAdapter,如下:

@Configuration(proxyBeanMethods = false)
@Import(EnableWebMvcConfiguration.class)
@EnableConfigurationProperties({ WebMvcProperties.class, ResourceProperties.class })
@Order(0)
public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer {}

WebMvcAutoConfigurationAdapter这个子配置类实现了WebMvcConfigurer这个接口,这个正是MVC扩展接口,这个就很清楚了。自动配置类是在项目启动的时候就加载的,因此Spring Boot会在项目启动时加载WebMvcAutoConfigurationAdapter这个MVC扩展配置类,提前完成一些默认的配置(比如内置了默认的视图解析器,资源映射处理器等等),这也就是为什么没有配置什么MVC相关的东西依然能够运行

如何全面接管MVC?【不推荐】

全面接管MVC是什么意思呢?全面接管的意思就是不需要Spring Boot自动配置,而是全部使用自定义的配置。

全面接管MVC其实很简单,只需要在配置类上添加一个@EnableWebMvc注解即可。还是添加拦截器,例子如下:

/**
* @EnableWebMvc:全面接管MVC,导致自动配置类失效
*/
@Configuration
@EnableWebMvc
public class WebMvcConfig implements WebMvcConfigurer {
@Autowired
private RepeatSubmitInterceptor repeatSubmitInterceptor; @Override
public void addInterceptors(InterceptorRegistry registry) {
//添加拦截器
registry.addInterceptor(repeatSubmitInterceptor).excludePathPatterns("/error");
}
}

一个注解就能全面接口MVC,是不是很爽,不过,不建议使用。

为什么@EnableWebMvc一个注解就能够全面接管MVC?

what???为什么呢?上面刚说过自动配置类WebMvcAutoConfiguration会在项目启动期间加载一些默认的配置,这会怎么添加一个@EnableWebMvc注解就不行了呢?

其实很简单,@EnableWebMvc源码如下:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {
}

其实重要的就是这个@Import(DelegatingWebMvcConfiguration.class)注解了,Spring中的注解,快速导入一个配置类DelegatingWebMvcConfiguration,源码如下:

@Configuration(proxyBeanMethods = false)
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {}

明白了,@EnableWebMvc这个注解实际上就是导入了一个WebMvcConfigurationSupport子类型的配置类而已

而WEB模块的自动配置类有这么一行注解@ConditionalOnMissingBean(WebMvcConfigurationSupport.class),源码如下:

@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,
ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {

这个注解@ConditionalOnMissingBean什么意思呢?简单的说就是IOC容器中没有指定的Bean这个配置才会生效。

一切都已经揭晓了,@EnableWebMvc导入了一个WebMvcConfigurationSupport类型的配置类,导致了自动配置类WebMvcAutoConfiguration标注的@@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)判断为false了,从而自动配置类失效了。

总结

扩展和全面接管MVC都很简单,但是不推荐全面接管MVC,一旦全面接管了,WEb模块的这个starter将没有任何意义,一些全局配置文件中与MVC相关的配置也将会失效。

扩展、接管MVC都不会,还会用Spring Boot?的更多相关文章

  1. 扩展、接管MVC都不会,还说会Spring Boot?

    持续原创输出,点击上方蓝字关注我 目录 前言 Spring Boot 版本 如何扩展MVC? 如何自定义一个拦截器? 什么都不配置为什么依然能运行MVC相关的功能? 如何全面接管MVC?[不推荐] 为 ...

  2. 大清朝早亡了,还没有入门 Spring Boot?

    由于读者的数量越来越多,难免会被问到一些我自己都觉得不好意思的问题,比如说前几天小王就问我:"二哥,快教教我,怎么通过 Spring Boot 创建一个 Hello World 项目啊?&q ...

  3. Spring Boot中如何扩展XML请求和响应的支持

    在之前的所有Spring Boot教程中,我们都只提到和用到了针对HTML和JSON格式的请求与响应处理.那么对于XML格式的请求要如何快速的在Controller中包装成对象,以及如何以XML的格式 ...

  4. Spring Boot中扩展XML请求和响应的支持

    在Spring Boot中,我们大多时候都只提到和用到了针对HTML和JSON格式的请求与响应处理.那么对于XML格式的请求要如何快速的在Controller中包装成对象,以及如何以XML的格式返回一 ...

  5. Spring Boot 2.x基础教程:如何扩展XML格式的请求和响应

    在之前的所有Spring Boot教程中,我们都只提到和用到了针对HTML和JSON格式的请求与响应处理.那么对于XML格式的请求要如何快速的在Controller中包装成对象,以及如何以XML的格式 ...

  6. Spring Boot 2.X(三):使用 Spring MVC + MyBatis + Thymeleaf 开发 web 应用

    前言 Spring MVC 是构建在 Servlet API 上的原生框架,并从一开始就包含在 Spring 框架中.本文主要通过简述 Spring MVC 的架构及分析,并用 Spring Boot ...

  7. spring boot中扩展spring mvc 源码分析

    首先,确认你是对spring boot的自动配置相关机制是有了解的,如果不了解请看我spring boot相关的源码分析. 通常的使用方法是继承自org.springframework.boot.au ...

  8. 这类注解都不知道,还好意思说会Spring Boot ?

    前言 不知道大家在使用Spring Boot开发的日常中有没有用过@Conditionalxxx注解,比如@ConditionalOnMissingBean.相信看过Spring Boot源码的朋友一 ...

  9. 这些保护Spring Boot 应用的方法,你都用了吗?

    这些保护Spring Boot 应用的方法,你都用了吗? 生如夏花 SpringForAll社区 今天 Spring Boot大大简化了Spring应用程序的开发.它的自动配置和启动依赖大大减少了开始 ...

随机推荐

  1. SSM框架之mybatis极速入门!

  2. 【Gin-API系列】部署和监控(九)

    本文是[Gin-API系列]的最后一篇文章,简单介绍如何在生产环境的部署架构和监控手段. 生产部署 部署架构 使用Nginx加Keepalived的方式搭建,可以达到高可用的效果,并可以横向扩容 如何 ...

  3. Oracle数据库访问客户端 sqldeveloper-19.2.1.247.2212-x64 下载

    Oracle数据库访问客户端 sqldeveloper-19.2.1.247.2212-x64 地址:https://pan.baidu.com/s/1iojCVxwXocyM8oObTf0xaw 这 ...

  4. Docker Compose 搭建 Redis Cluster 集群环境

    在前文<Docker 搭建 Redis Cluster 集群环境>中我已经教过大家如何搭建了,本文使用 Docker Compose 再带大家搭建一遍,其目的主要是为了让大家感受 Dock ...

  5. elasticsearch跨集群数据迁移

    写这篇文章,主要是目前公司要把ES从2.4.1升级到最新版本7.8,不过现在是7.9了,官方的文档:https://www.elastic.co/guide/en/elasticsearch/refe ...

  6. 跟我一起学.NetCore之静态文件处理的那些事

    前言 如今前后端分离开发模式如火如荼,开发职责更加分明(当然前后端一起搞的模式也没有完全褪去):而对于每个公司产品实施来说,部署模式会稍有差别,有的会单独将前端文件部署为一个站点,有的会将前端文件和后 ...

  7. Vue搭建组件库并发布到 npm

    https://www.jianshu.com/p/72d303449abc

  8. MyBatis学习(三)日志输出环境配置

    一.编写日志输出环境配置文件 在开发过程中,最重要的就是在控制台查看程序输出的日志信息,在这里我们选择使用 log4j 工具来输出: 准备工作:将[MyBatis]文件夹下[lib]中的 log4j ...

  9. Processing 网格纹理制作(棋盘格)

    写在前面的话 很久没有写博文了.最近在整理Processing有关文档,看到之前做的一些例子,想着分享在互联网上,当然和以前一样,目前也仅为了给初学者有个学习参考,笔者能力有限.废话不多说,干就完事了 ...

  10. Mac OS X中Apache开启ssl

    升级ios7.1之后用那个企业证书打测试包网页上不能下载,提示Mainfest.plist需要用https,然后就看了下Apache的https的设置,虽然后来还是不行,先略下不表,下文再说,把这个过 ...