10 SpringBoot全面接管SpringMVC
Spring Boot官方文档描述
If you want to keep Spring Boot MVC features and you want to add additional MVC configuration (interceptors, formatters, view controllers, and other features), you can add your own @Configuration class of type WebMvcConfigurer but without @EnableWebMvc. If you wish to provide custom instances of RequestMappingHandlerMapping, RequestMappingHandlerAdapter, or ExceptionHandlerExceptionResolver, you can declare a WebMvcRegistrationsAdapter instance to provide such components.
If you want to take complete control of Spring MVC, you can add your own @Configuration annotated with @EnableWebMvc.
在实际开发中,仅靠SpringBoot的这点自动配置是不够用的。比如,以前有SpringMVC配置文件的时候:
1. 原来的SpringMVC配置方式:
<mvc:view-controller path="/hello" view-name="success"/><!-- 配置文件设置页面跳转,发一个请求到页面,就没必要写空方法了,配一下即可 -->
<mvc:interceptors>
<mvc:interceptor><!-- SpringMvc 拦截器 -->
<mvc:mapping path="/hello"/>
<bean class=""></bean>
</mvc:interceptor>
</mvc:interceptors>
2. 现在的SpringBoot方式实现:
add your own @Configuration class of type WebMvcConfigurer but without @EnableWebMvc
编写一个配置类(@Configuration),是WebMvcConfigurer(SpringBoot2.1.0))【WebMvcConfigurerAdapter(SpringBoot1.5.10)】类型;不能标注@EnableWebMvc
既保留了所有的自动配置,也能用我们扩展的配置;
@Configuration
public class MyConfig implements WebMvcConfigurer {
/**
* 浏览器发送addViewTest请求,来到success页面
* 发请求到页面,就没有必要在Controller里写空方法了,直接来做视图映射
*/
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/addViewTest").setViewName("success");
} }


原理

public class WebMvcAutoConfiguration { @Configuration
@Import({WebMvcAutoConfiguration.EnableWebMvcConfiguration.class})
@EnableConfigurationProperties({WebMvcProperties.class, ResourceProperties.class})
@Order(0)
public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer, ResourceLoaderAware { } @Configuration
public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration { }
}@Configuration
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite(); public DelegatingWebMvcConfiguration() {
} /*从容器中注入所有的WebMvcConfigurer*/
@Autowired(
required = false
)
public void setConfigurers(List<WebMvcConfigurer> configurers) {
if (!CollectionUtils.isEmpty(configurers)) {
this.configurers.addWebMvcConfigurers(configurers);
} }
/*格式化*/
protected void addFormatters(FormatterRegistry registry) {
this.configurers.addFormatters(registry);
}
/*拦截器*/
protected void addInterceptors(InterceptorRegistry registry) {
this.configurers.addInterceptors(registry);
}
/*资源文件*/
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
this.configurers.addResourceHandlers(registry);
}
/*视图映射*/
protected void addViewControllers(ViewControllerRegistry registry) {
this.configurers.addViewControllers(registry);
}
protected void configureViewResolvers(ViewResolverRegistry registry) {
this.configurers.configureViewResolvers(registry);
}
/*参数解析*/
protected void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
this.configurers.addArgumentResolvers(argumentResolvers);
} ......
}真正调用的实现类
class WebMvcConfigurerComposite implements WebMvcConfigurer {
private final List<WebMvcConfigurer> delegates = new ArrayList(); //在上一个类中的依赖注入方法中调用的正是此方法,将所有的容器中的配资类加载到本地成员变量中
public void addWebMvcConfigurers(List<WebMvcConfigurer> configurers) {
if (!CollectionUtils.isEmpty(configurers)) {
this.delegates.addAll(configurers);
}
}
/**
* 以下的每一个方法都是循环遍历容器中实现了WebMvcConfigurer接口的所有的bean,并调用相应的处理方法*/
public void configurePathMatch(PathMatchConfigurer configurer) {
Iterator var2 = this.delegates.iterator(); while(var2.hasNext()) {
WebMvcConfigurer delegate = (WebMvcConfigurer)var2.next();
delegate.configurePathMatch(configurer);
} }
//遍历所有的WebConfiguration类 并调用视图解析方法
public void addViewControllers(ViewControllerRegistry registry) {
Iterator var2 = this.delegates.iterator(); while(var2.hasNext()) {
WebMvcConfigurer delegate = (WebMvcConfigurer)var2.next();
delegate.addViewControllers(registry);
} }public void addFormatters(FormatterRegistry registry) {...} ..........}
3)、容器中所有的WebMvcConfigurer都会一起起作用;
4)、所以我们的配置类MyConfig也会被调用()
效果:SpringMVC的自动配置 和 我们的扩展配置 都会起作用;
3、全面接管SpringMVC
SpringBoot对SpringMVC的自动配置不需要了,所有都是我们自己配置;所有的SpringMVC的自动配置都失效了
If you want to take complete control of Spring MVC, you can add your own @Configuration annotated with @EnableWebMvc.
我们需要在配置类中添加@EnableWebMvc即可,(除非功能简单,你想节省内存空间,要不然不建议全面接管)
-
//使用WebMvcConfigurerAdapter可以来扩展SpringMVC的功能
@EnableWebMvc
@Configuration
public class MyMvcConfig extends WebMvcConfigurerAdapter { @Override
public void addViewControllers(ViewControllerRegistry registry) {
// super.addViewControllers(registry);
//浏览器发送 /atguigu 请求来到 success
registry.addViewController("/atguigu").setViewName("success");
}
}
原理:
为什么@EnableWebMvc自动配置就失效了;
1)@EnableWebMvc的核心
@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {
2)、
@Configuration
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
3)、
@Configuration
@ConditionalOnWebApplication
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class,
WebMvcConfigurerAdapter.class })
//容器中没有这个组件的时候,这个自动配置类才生效
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class,
ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {
4)、@EnableWebMvc将WebMvcConfigurationSupport组件导入进来;
5)、导入的WebMvcConfigurationSupport只是SpringMVC最基本的功能;
5、如何修改SpringBoot的默认配置模式:
1)、SpringBoot在自动配置很多组件的时候,先看容器中有没有用户自己配置的(@Bean、@Component)如果有就用用户配置的,如果没有,才自动配置;
如果有些组件可以有多个(ViewResolver)将用户配置的和自己默认的组合起来;
2)、在SpringBoot中会有非常多的xxxConfigurer帮助我们进行扩展配置
3)、在SpringBoot中会有很多的xxxCustomizer帮助我们进行定制配置
10 SpringBoot全面接管SpringMVC的更多相关文章
- SpringBoot接管SpringMvc
SpringBoot接管SpringMvc Spring Web MVC framework(通常简称为“Spring MVC”)是一个丰富的“model 视图控制器”web framework. S ...
- 【串线篇】spring boot全面接管springMvc
一.Spring MVC auto-configuration Spring Boot 自动配置好了SpringMVC 以下是SpringBoot对SpringMVC的默认配置:(WebMvcAutoC ...
- SpringBoot中对SpringMVC的自动配置
https://docs.spring.io/spring-boot/docs/1.5.10.RELEASE/reference/htmlsingle/#boot-features-developin ...
- Springboot学习:SpringMVC自动配置
Spring MVC auto-configuration Spring Boot 自动配置好了SpringMVC 以下是SpringBoot对SpringMVC的默认配置:==(WebMvcAuto ...
- SpringBoot:扩展SpringMVC、定制首页、国际化
目录 扩展使用SpringMVC 如何扩展SpringMVC 为何这么做会生效(原理) 全面接管SpringMVC 首页实现 页面国际化 SpringBoot扩展使用SpringMVC.使用模板引擎定 ...
- SpringBoot | 4.1 SpringMVC的自动配置
目录 前言 1. SpringMVC框架的设计与流程 1.1 SpringMVC框架的示意图 1.2 SpringMVC的组件流程 2. *自动配置的源码分析 2.1 导入Web场景启动器 2.2 找 ...
- 10.spring-boot基于角色的权限管理页面实现
10.spring-boot基于角色的权限管理页面实现
- 58、springmvc-定制与接管SpringMVC
58.springmvc-定制与接管SpringMVC 定制SpringMVC: 1).@EnableWebMvc:开启SpringMVC定制配置功能: <mvc:annotation-driv ...
- 0011SpringBoot的@EnableWebMvc全面接管SpringMVC的自动配置(源码)
所谓的@EnableWebMvc全面接管SpringMVC的自动配置,是指@EnableWebMvc注解会使SpringMVC的自动配置失效,原理如下: 1.查看@EnableWebMvc的源码,如下 ...
随机推荐
- obj.attr = 5 == obj._dict_["attr"] = 5,调用super相当于调用父类方法进行重新构造
- codeforces439B
Devu, the Dumb Guy CodeForces - 439B Devu is a dumb guy, his learning curve is very slow. You are su ...
- BZOJ1926[Sdoi2010]粟粟的书架——二分答案+主席树
题目描述 幸福幼儿园 B29 班的粟粟是一个聪明机灵.乖巧可爱的小朋友,她的爱好是画画和读书,尤其喜欢 Thomas H. Co rmen 的文章.粟粟家中有一个 R行C 列的巨型书架,书架的每一个位 ...
- BZOJ1124 POI2008枪战Maf(环套树+贪心)
每个点出度都为1,可以发现这张图其实是个环套树森林,树中儿子指向父亲,环上边同向. 首先自环肯定是没救的,先抬出去. 要使死亡人数最多的话,显然若一个点入度为0其不会死亡,而一个孤立的环至少会留下一个 ...
- 自学Linux Shell4.1-监测程序ps top kill
点击返回 自学Linux命令行与Shell脚本之路 4.1-监测程序ps top kill 1. PS命令 linux中的ps命令是Process Status的缩写.ps命令用来列出系统中当前运行的 ...
- 学习Spring Boot:(二十六)使用 RabbitMQ 消息队列
前言 前面学习了 RabbitMQ 基础,现在主要记录下学习 Spring Boot 整合 RabbitMQ ,调用它的 API ,以及中间使用的相关功能的记录. 相关的可以去我的博客/RabbitM ...
- java freemarker导出word时添加或勾选复选框
最近项目导出word碰到一个需求,要求根据数据动态的决定word里的复选框是否勾选, 公司导出word用的是freemarker,相比较其他技术,freemarker可以很容易的控制输出样式, 在wo ...
- NOIP2013题解
NOIP2013题解 Day1 转圈游戏 circle 快速幂模板题. #include<iostream> using namespace std; int n,m,k,x; int f ...
- luogu1972 HH的项链(树状数组)
无修改.询问区间种类数的问题可以很容易地用树状数组解决 我们先给询问按右端点排序,然后推着做,每次让a[i]++,表示i处新增了一个种类 但是这样会和前面的有重复,我们只要记下每个种类上次在哪里出现过 ...
- 【LOJ#10180】烽火传递 单调队列+dp
题目大意:给定一个 N 个非负整数数组成的序列,每个点有一个贡献值,现选出其中若干数,使得每连续的 K 个数中至少有一个数被选,要求选出的数贡献值最小. 题解:设 \(dp[i]\) 表示考虑了序列前 ...