【SpringBoot】SpringBoot与SpringMVC自动配置(五)
本文介绍SpringBoot对Spring MVC自动配置,SpringBoot自动配置原理可以参考:【SpringBoot】SpringBoot配置与单元测试(二)
首先新建一个SpringBoot的web项目,参考:【SpringBoot】SpringBoot快速入门(一)
本例pom文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>com.test</groupId>
<artifactId>test-springboot-web</artifactId>
<version>1.0-SNAPSHOT</version> <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
</parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <!--引入jquery-webjar-->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.3.1</version>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency> </dependencies> <!-- SpringBoot打包插件,可以将代码打包成一个可执行的jar包 -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
SpringMVC自动配置
自动配置在Spring的默认值之上添加了以下功能:
- 包含
ContentNegotiatingViewResolver
和BeanNameViewResolver
。 - 支持服务静态资源,包括对WebJars的支持。
- 自动注册
Converter
,GenericConverter
和Formatter
豆类。 - 支持
HttpMessageConverters
。 - 自动注册
MessageCodesResolver
。 - 静态
index.html
支持。 - 定制
Favicon
支持。 - 自动使用
ConfigurableWebBindingInitializer
bean。
如果想保留Spring Boot MVC功能,并且想要添加其他MVC配置(拦截器,格式化程序,视图控制器和其他功能),则可以编写一个配置类(@Configuration),并
实现WebMvcConfigurer接口的类,但不能加 @EnableWebMvc
。如果您希望提供,或的自定义实例RequestMappingHandlerMapping
,则可以声明一个实例来提供此类组件。RequestMappingHandlerAdapter、
ExceptionHandlerExceptionResolver、
WebMvcRegistrationsAdapter
如果想完全控制Spring MVC,可以在配置类(@Configuration)添加上
注释@EnableWebMvc
。
添加MVC配置类
1、原理:
1)、WebMvcAutoConfiguration是SpringMVC的自动配置类
2)、在做其他自动配置时会导入;@Import(EnableWebMvcConfiguration.class)
3)、容器中所有的WebMvcConfigurer都会一起起作用;
4)、我们的配置类也会被调用;
2、编写一个配置类(@Configuration),实现WebMvcConfigurer接口;不能标注@EnableWebMvc;
这样既保留了所有的自动配置(WebMvcAutoConfiguration),也能用我们扩展的配置;
// @EnableWebMvc // 全面接管SpringMVC,所有的WebMvc自动配置都失效,如静态资源的访问都失效
@Configuration
public class MyMvcConfig implements WebMvcConfigurer { @Override
public void addViewControllers(ViewControllerRegistry registry) {
// 浏览器访问 "/success2" 重定向到 "/success"
registry.addRedirectViewController("/success2", "/success");
// 浏览器访问 "/success2" 转发 "/success"
registry.addViewController("/success3").setViewName("/success");
}
}
3、验证:效果SpringMVC的自动配置和我们的扩展配置都会起作用
重定向请求验证地址:http://localhost:8080/success
转发请求验证地址:http://localhost:8080/success
全面接管SpringMVC
1、原理
1)、查看源码WebMvcAutoConfiguration类,有条件注解,在没有WebMvcConfigurationSupport类的情况下才注入
@Configuration
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
// 条件判断:在没有WebMvcConfigurationSupport类的情况下才注入
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,
ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {
2)、查看@EnableWebMvc注解源码,发现它导入DelegatingWebMvcConfiguration类
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
// 导入DelegatingWebMvcConfiguration类
@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {
}
DelegatingWebMvcConfiguration类继承了WebMvcConfigurationSupport类
@Configuration
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
3)、@EnableWebMvc将WebMvcConfigurationSupport组件导入进来,导入的WebMvcConfigurationSupport只是SpringMVC最基本的功能,WebMvcAutoConfiguration类又是在没有WebMvcConfigurationSupport组件情况下生效,所以@EnableWebMvc能使WebMvcAutoConfiguration失效,并全面接管SpringMVC
静态资源的映射规则
SpringBoot对静态文件映射都在类中WebMvcAutoConfiguration,自动配置好了,打开WebMvcAutoConfiguration类,并分析
1、规则:/webjars/**
规则:所有 /webjars/** ,都去 classpath:/META-INF/resources/webjars/ 找资源;
webjars:以jar包的方式引入静态资源; 官网地址:http://www.webjars.org/
// 添加静态资源映射
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
return;
}
Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
if (!registry.hasMappingForPattern("/webjars/**")) {
// 添加映射
customizeResourceHandlerRegistration(registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/")
.setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
String staticPathPattern = this.mvcProperties.getStaticPathPattern();
if (!registry.hasMappingForPattern(staticPathPattern)) {
customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern)
.addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations()))
.setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
}
测试:在pom文件中引入依赖
<!--引入jquery-webjar-->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.3.1</version>
</dependency>
可以看到jar包中有jquery.js文件
验证:重启项目,浏览器上打开地址:http://localhost:8080/webjars/jquery/3.3.1/jquery.js,即可看到能获取到js文件
2、规则:/**
"/**" 访问当前项目的任何资源,都去(静态资源的文件夹)找映射,静态资源的文件夹如下:
"classpath:/META-INF/resources/",
"classpath:/resources/",
"classpath:/static/",
"classpath:/public/"
测试:在类路径中,创建static文件夹,在其中添加一个测试页面test.html
验证:重启项目,浏览器使用地址:http://localhost:8080/test.html,访问,即可看到test页面
3、规则:首页
首页映射规则代码在类中WebMvcAutoConfiguration,如下,也在静态文件夹(即规则2下的文件夹)下查找
// 添加首页映射
@Bean
public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext) {
WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(
new TemplateAvailabilityProviders(applicationContext), applicationContext, getWelcomePage(),
this.mvcProperties.getStaticPathPattern());
welcomePageHandlerMapping.setInterceptors(getInterceptors());
return welcomePageHandlerMapping;
}
测试:在类路径中的static文件夹,在其中添加一个欢迎页面index.html
验证:重启项目,浏览器使用地址:http://localhost:8080,访问,即可看到欢迎页面
4、规则:**/favicon.ico
所有的 **/favicon.ico 都是在静态资源文件(即规则2下的文件夹)下找;
首页映射规则代码在类中WebMvcAutoConfiguration,如下
// 配置站点的图标映射
@Configuration
@ConditionalOnProperty(value = "spring.mvc.favicon.enabled", matchIfMissing = true)
public static class FaviconConfiguration implements ResourceLoaderAware { private final ResourceProperties resourceProperties; private ResourceLoader resourceLoader; public FaviconConfiguration(ResourceProperties resourceProperties) {
this.resourceProperties = resourceProperties;
} @Override
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
} @Bean
public SimpleUrlHandlerMapping faviconHandlerMapping() {
SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
mapping.setOrder(Ordered.HIGHEST_PRECEDENCE + 1);
mapping.setUrlMap(Collections.singletonMap("**/favicon.ico", faviconRequestHandler()));
return mapping;
} @Bean
public ResourceHttpRequestHandler faviconRequestHandler() {
ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler();
requestHandler.setLocations(resolveFaviconLocations());
return requestHandler;
} private List<Resource> resolveFaviconLocations() {
String[] staticLocations = getResourceLocations(this.resourceProperties.getStaticLocations());
List<Resource> locations = new ArrayList<>(staticLocations.length + 1);
Arrays.stream(staticLocations).map(this.resourceLoader::getResource).forEach(locations::add);
locations.add(new ClassPathResource("/"));
return Collections.unmodifiableList(locations);
} }
测试:在类路径中的static文件夹,在其中添加一个favicon.ico图标
验证:重启项目,浏览器使用地址:http://localhost:8080,访问,即可看到浏览器标题上的站点图标已改变
【SpringBoot】SpringBoot与SpringMVC自动配置(五)的更多相关文章
- Springboot学习:SpringMVC自动配置
Spring MVC auto-configuration Spring Boot 自动配置好了SpringMVC 以下是SpringBoot对SpringMVC的默认配置:==(WebMvcAuto ...
- SpringBoot源码学习系列之SpringMVC自动配置
目录 1.ContentNegotiatingViewResolver 2.静态资源 3.自动注册 Converter, GenericConverter, and Formatter beans. ...
- SpringBoot:配置文件及自动配置原理
西部开源-秦疆老师:基于SpringBoot 2.1.6 的博客教程 秦老师交流Q群号: 664386224 未授权禁止转载!编辑不易 , 转发请注明出处!防君子不防小人,共勉! SpringBoot ...
- SpringBoot是如何实现自动配置的?--SpringBoot源码(四)
注:该源码分析对应SpringBoot版本为2.1.0.RELEASE 1 前言 本篇接 助力SpringBoot自动配置的条件注解ConditionalOnXXX分析--SpringBoot源码(三 ...
- SpringBoot Beans管理和自动配置
原 SpringBoot Beans管理和自动配置 火推 02 2017年12月20日 21:37:01 阅读数:220 SpringBoot Beans管理和自动配置 @SpringBootAppl ...
- SpringBoot自定义starter及自动配置
SpringBoot的核心就是自动配置,而支持自动配置的是一个个starter项目.除了官方已有的starter,用户自己也可以根据规则自定义自己的starter项目. 自定义starter条件 自动 ...
- 这一次搞懂SpringBoot核心原理(自动配置、事件驱动、Condition)
@ 目录 前言 正文 启动原理 事件驱动 自动配置原理 Condition注解原理 总结 前言 SpringBoot是Spring的包装,通过自动配置使得SpringBoot可以做到开箱即用,上手成本 ...
- SpringBoot扩展SpringMVC自动配置
SpringBoot中自动配置了 ViewResolver(视图解析器) ContentNegotiatingViewResolver(组合所有的视图解析器) 自动配置了静态资源文件夹.静态首页.fa ...
- SpringBoot日记——SpringMvc自动配置与扩展篇
为了让SpringBoot保持对SpringMVC的全面支持和扩展,而且还要维持SpringBoot不写xml配置的优势,我们需要添加一些简单的配置类即可实现: 通常我们使用的最多的注解是: @Bea ...
随机推荐
- zabbix--钉钉告警
zabbix 钉钉告警机制 群机器人是钉钉群的高级扩展功能,群机器人可以将第三方服务的信息聚合到群聊中,实现自动化的信息同步.例如:通过聚合GitHub,GitLab等源码管理服务,实现源码更新同步: ...
- httprunner学习9-完整的用例结构(yaml&json)
前言 前面几篇零散的学了一些httprunner的知识点,那么一个完整的 YAML/JSON 用例文件包含哪些关键字呢? 测试用例结构 在 HttpRunner 中,测试用例组织主要基于三个概念: 测 ...
- vue-cli配置移动端自适应flexible.js
第一部分:项目中引入lib-flexible 一.项目中安装lib-flexible npm install lib-flexible --save-dev 二.在项目入口文件main.js中引入li ...
- oc语言的特征
类型结构+运行时 内存管理:引用计数与析构 并发:gcd 函数式:block
- Tomcat不能访问ln -s软连接文件夹的前因后果
为了部署方便,把webapps下的大文件(图片等资源)放到工程外,通过软连接的方式设置 命令最常用的参数是-s,具体用法是:ln -s 源文件 目标文件. ln -s /usr/local/pic/i ...
- pytcharm无法debug:pydev debugger: process 15188 is connecting
今天问老师,老师说需要设置断点,果然设置断点后就可以正常调试了.
- .NET总结--泛型与泛型集合,应用场景
泛型优点 1.提高代码复用性,代码简洁直观 2.直接存储数据类型免去数据类型之间得隐式转换 3.免去拆箱装箱过程,提高效率 4.数据类型安全,存储时会验证是否对应该类型 泛型集合 一. ArrayLi ...
- JDBC-select练习&jdbc工具类&数据库登录案例
一.select练习 1.说明 练习: * 定义一个方法,查询emp表的数据将其封装为对象,然后装载集合,返回. 1. 定义Emp类 2. 定义方法 public List<Emp> fi ...
- pandas批量读取带有日期的文件夹简单操作
工作中碰到了这样一个数据处理的问题,想让你把某个文件夹下的子文件夹中的excel表级联成为1张表,用excel来做会很浪费时间并且很劳累,这时候我们就可以用pandas来加大工作效率,只需要半个小时就 ...
- linux高性能服务器编程 (三) --TCP协议详解
第三章 IP协议详解 TCP协议是TCP/IP协议族中的另外一个重要的协议,与IP协议相比,TCP协议更高进应用层.一些重要的socket选项都和TCP协议相关.这一章主要从如下方面学习: 1)TCP ...