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

目录

  • 前言
  • 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. 09vuex

    state 大白话:获取state的值 vuex中state数据是响应式的.只要state中数据发生变化.vue组件自动更新. 要想做到响应式 前提:是在mutaion中定义函数修改state值. 最 ...

  2. 求支付表中按id累积和最接近100的那条记录

    此例源自美团的一道SQL面试题 支付表结构: create table hy_payment( id number(4,0) primary key, pay number(3,0) not null ...

  3. 取得min和max之间包括端点的随机整数

    产生随机数的函数用处不少,写一个放博客里备用,函数如下: /** * get a random integer between min and max * @param min * @param ma ...

  4. zookeeper与分布式系统

    1.1. 分布式系统基础知识 一个tomcat打天下的时代,不能说完全淘汰了,在一个管理系统,小型项目中还经常使用,这并不过分,出于成本的考虑,这反而值得提倡. 1.1.1.   分布式系统是什么 分 ...

  5. PHP复杂变量

    eval($str="${${phpinfo()}}";)     →   可以执行phpinfo() ${phpinfo()} = {${phpindo()}} PHP复杂变量 ...

  6. 容器服务 TKE 上服务暴露的几种方式

    预备知识 1. K8S 上 Service 类型 ClusterIP 通过集群的内部 IP 暴露服务,选择该值,服务只能够在集群内部可以访问,这也是默认的 ServiceType. NodePort ...

  7. Linked List 单向链表

    Linked List 链表的理解 小结 链表是以节点的方式来储存的 每个节点包括 data域:存放数据,next域:指向下一个节点 如图:发现链表的各个节点不一定是连续储存的 链表分为带头节点的链表 ...

  8. 安装Linux的CentOS操作系统 - 初学者系列 - 学习者系列文章

    Linux系统对于一些熟悉Windows操作系统的用户来说可能比较陌生,但是它也是一种多用户.多任务的操作系统,现在也发展成为了多种版本的操作系统了.如果想对该系统进行学习,请下载这个学习文档:htt ...

  9. Netty中的一些注意事项--底层基础

    转载自http://www.mamicode.com/info-detail-1215305.html 最近开发了一个纯异步的redis客户端,算是比较深入的使用了一把netty.在使用过程中一边优化 ...

  10. hystrix(8) 插件

    上一节讲到HystrixCommand的执行流程. Hystrix内部将一些模块实现成了插件,并且提供了用户提供自己的实现,通过配置来替换插件.Hystrix提供了5个插件,分别为并发相关插件(Hys ...