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

目录

  • 前言
  • 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. 从String中移除空白字符的多种方式!?

    字符串,是Java中最常用的一个数据类型了.我们在日常开发时候会经常使用字符串做很多的操作.比如字符串的拼接.截断.替换等. 这一篇文章,我们介绍一个比较常见又容易被忽略的一个操作,那就是移除字符串中 ...

  2. C002:计算球体体积(半径固化)

    程序: #include "stdafx.h" int _tmain(int argc, _TCHAR* argv[]) { float sphereRadius=10.0f; f ...

  3. JsonAnalyzer2 1.01版

    本版的改进主要在字符串的处理,前版不允许出现[]{},:等,现在都可以了,做出的修改主要在Lexer类,另外Token类增加1了下标,TreeBuilder类的不合语法处也做出一定修改. 测试用例:h ...

  4. docker 容器中部署 Go 服务时,请求 https 文件时抛错

    错误提示: Get https://res.ddkt365.com/ddktRes/imageRes/wx_headimg/0f1d9e55913c22bcaf7cca9b38048d29.jpeg: ...

  5. 下载安装gradle

    1.登录官网:www.gradle.org,进入到下图的界面: 2.点击Install Gradle,跳转到下一个界面后: 3.下载 4.下载成功后,解压到任意位置,将路径添加到path路径下,选择我 ...

  6. jenkins参数传递

    官方说明:https://wiki.jenkins.io/display/JENKINS/Parameterized+Build 1.添加参数传递 参数类型解析: 2.在 Execute shell ...

  7. Docker镜像下载很慢,各种加速无效

    mcr.microsoft.com/dotnet/......   改成: dockerhub.azk8s.cn/dotnet/...... 或 mcr.azk8s.cn/dotnet/......

  8. 整理的网上的MySQL优化文章总结

    MySQL优化 Linux优化 IO优化 调整Linux默认的IO调度算法. IO调度器的总体目标是希望让磁头能够总是往一个方向移动,移动到底了再往反方向走,这恰恰就是现实生活中的电梯模型,所以IO调 ...

  9. C#开发PACS医学影像处理系统(十一):Dicom影像挂片协议

    通俗点说,挂片协议可以看作整个系统的一个相对复杂一点的配置文件,可以用JSON或XML格式来读取与保存, 另外,可以制作一个独立的exe配置程序来管理这些挂片协议. 假设配置了CT的挂片协议的右键菜单 ...

  10. 阿里云docker部署mysql

    看完我的上一个博客之后,对centos系统应该有一定的了解,话不多说,接下来我们来在docker容器中部署mysql. 1.下载mysql镜像,因为本人用的5.7版本,你也可以下载最新版,都是可以的 ...