扩展、接管MVC都不会,还会用Spring Boot?
持续原创输出,点击上方蓝字关注我

目录
前言 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其实很简单,只需要以下步骤:
创建一个MVC的配置类,并且标注 @Configuration注解。实现 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?的更多相关文章
- 扩展、接管MVC都不会,还说会Spring Boot?
持续原创输出,点击上方蓝字关注我 目录 前言 Spring Boot 版本 如何扩展MVC? 如何自定义一个拦截器? 什么都不配置为什么依然能运行MVC相关的功能? 如何全面接管MVC?[不推荐] 为 ...
- 大清朝早亡了,还没有入门 Spring Boot?
由于读者的数量越来越多,难免会被问到一些我自己都觉得不好意思的问题,比如说前几天小王就问我:"二哥,快教教我,怎么通过 Spring Boot 创建一个 Hello World 项目啊?&q ...
- Spring Boot中如何扩展XML请求和响应的支持
在之前的所有Spring Boot教程中,我们都只提到和用到了针对HTML和JSON格式的请求与响应处理.那么对于XML格式的请求要如何快速的在Controller中包装成对象,以及如何以XML的格式 ...
- Spring Boot中扩展XML请求和响应的支持
在Spring Boot中,我们大多时候都只提到和用到了针对HTML和JSON格式的请求与响应处理.那么对于XML格式的请求要如何快速的在Controller中包装成对象,以及如何以XML的格式返回一 ...
- Spring Boot 2.x基础教程:如何扩展XML格式的请求和响应
在之前的所有Spring Boot教程中,我们都只提到和用到了针对HTML和JSON格式的请求与响应处理.那么对于XML格式的请求要如何快速的在Controller中包装成对象,以及如何以XML的格式 ...
- Spring Boot 2.X(三):使用 Spring MVC + MyBatis + Thymeleaf 开发 web 应用
前言 Spring MVC 是构建在 Servlet API 上的原生框架,并从一开始就包含在 Spring 框架中.本文主要通过简述 Spring MVC 的架构及分析,并用 Spring Boot ...
- spring boot中扩展spring mvc 源码分析
首先,确认你是对spring boot的自动配置相关机制是有了解的,如果不了解请看我spring boot相关的源码分析. 通常的使用方法是继承自org.springframework.boot.au ...
- 这类注解都不知道,还好意思说会Spring Boot ?
前言 不知道大家在使用Spring Boot开发的日常中有没有用过@Conditionalxxx注解,比如@ConditionalOnMissingBean.相信看过Spring Boot源码的朋友一 ...
- 这些保护Spring Boot 应用的方法,你都用了吗?
这些保护Spring Boot 应用的方法,你都用了吗? 生如夏花 SpringForAll社区 今天 Spring Boot大大简化了Spring应用程序的开发.它的自动配置和启动依赖大大减少了开始 ...
随机推荐
- JVM—01
目录 1.1 JVM系统架构图 2.1 类加载器 2.1.1 双亲委派机制 2.1.2 沙箱安全机制 3.1 Native 4.1 PC寄存器 1.1 JVM系统架构图 JVM是什么? JVM是Jav ...
- Activiti7 任务人员动态分配(理论)
之前一直用的流程模型都是,固态的,写死的 由于固定分配方式,任务只能一步一步执行,执行到每一个任务将按照bpmn的配置去分配任务负责人.这显然在实际开发中是不可能的 所以我们需要动态分配人员 表达式分 ...
- MyBatis的逆向工程、Example类
public void testFindUserByName(){ //通过criteria构造查询条件 UserExample userExample = new UserExample(); us ...
- centOS7 设置mysql数据库外网可以访问
1.查看目前防火墙是否对外开发了3306端口 firewall-cmd --list-all 2.查看3306端口是否开放 firewall-cmd --query-port=3306/tcp no ...
- leetcode题目,个人见解1
给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一. 最高位数字存放在数组的首位, 数组中每个元素只存储单个数字. 你可以假设除了整数 0 之外,这个整数不会以零开头. 示例 1: 输入 ...
- Java模拟实现扫雷功能
//棋子 public class Chess { private boolean isBoomb=false; private int id;//下标 //点击方法 public int click ...
- 矩阵LU分解的MATLAB与C++实现
一:矩阵LU分解 矩阵的LU分解目的是将一个非奇异矩阵\(A\)分解成\(A=LU\)的形式,其中\(L\)是一个主对角线为\(1\)的下三角矩阵:\(U\)是一个上三角矩阵. 比如\(A= \beg ...
- TP6.0多应用模式隐藏路由中的应用名
本文默认采用的是多应用模式 PHP技术群: 159789818 ThinkPHP技术群: 828567087 1. 多应用模式中隐藏路由中的应用名的三种方式 域名绑定应用 增加应用入口 入口文件绑定应 ...
- centos 遇到/dev/mapper/cl-root 100% 解决方法
yum安装docker时报错[Errno 2] No usable temporary directory found in ['/tmp', '/var/tmp', '/usr/tmp', '/'] ...
- selenium中Xpath标签定位和cssSelectors定位(优先用cssSelectors)
二者的区别:xpath 支持角标定位,cssselector不支持 1.XPath是XML的路径语言,通俗一点讲就是通过元素的路径来查找到这个标签元素. xpath支持属性定位,无论是默认属性还是自定 ...