文章采用Spring Boot的源码版本为2.2.6。
从源码浅读,到具体体现。
0x01.Spring Boot 对静态资源的映射
- Spring Boot中,SpringMVC的相关配置全部在类
WebMvcutoConfiguration
中。
- 我们可以从中了解Spring Boot对静态资源的映射规则。
1.查看addResourceHandlers
方法:
- 该方法是增加资源映射的方法,在里面映射了
/webjars/
,同时映射了静态资源文件夹。
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
return;
}
Integer cachePeriod = this.resourceProperties.getCachePeriod();
if (!registry.hasMappingForPattern("/webjars/**")) {
customizeResourceHandlerRegistration(
registry.addResourceHandler("/webjars/**")
.addResourceLocations(
"classpath:/META-INF/resources/webjars/")
.setCachePeriod(cachePeriod));
}
String staticPathPattern = this.mvcProperties.getStaticPathPattern();
//静态资源文件夹映射
if (!registry.hasMappingForPattern(staticPathPattern)) {
customizeResourceHandlerRegistration(
registry.addResourceHandler(staticPathPattern)
.addResourceLocations(
this.resourceProperties.getStaticLocations())
.setCachePeriod(cachePeriod));
}
}
- 我们首先发现,在这个位置设置了缓存时间:
- 继续跟踪下去:
-
我们可以发现,静态资源有关的参数,缓存时间等都在这个类中进行设置。
-
我们还可以发现,所有对
/webjars/**
的请求 ,都会去classpath:/META-INF/resources/webjars/
找资源。
webjars
是以jar包的方式引入静态资源。我们可以去webjars的官网查找对应的坐标:
http://www.webjars.org/
例如:引入bootstrap的jar包形式:
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>4.0.0</version>
</dependency>
- 我们可以去相应的地方看到对应的静态资源。
-
继续看下边的代码,在下面添加了一个静态资源文件夹的映射:
-
跟踪下去:
-
也就是说,访问当前的任何资源,都会默认去下面的路径找,我们继续跟踪一下:
-
我们可以发现,它是一个字符串数组,也就是说,默认会去这几个目录寻找资源。
- "classpath:/META-INF/resources/",
- "classpath:/resources/",
- "classpath:/static/",
- "classpath:/public/"
2.查看WelcomePageHandlerMapping
方法:
- 该方法是对欢迎页面的映射。
@Bean
public WelcomePageHandlerMapping welcomePageHandlerMapping(
ResourceProperties resourceProperties) {
return new WelcomePageHandlerMapping(resourceProperties.getWelcomePage(),
this.mvcProperties.getStaticPathPattern());
}
- 我们先来看一下它获取的欢迎页是哪个页面:
- 我们发现,这些静态文件夹的路径都拼接上了
index.html
。 - 再来看一下被谁映射:
- 也就是说,静态资源文件夹下的所有
index.html
页面;被"/**"
映射。
3.总结
- 从上述的源码中,可以得到,Spring Boot的一些常用的静态资源映射关系。
(1)所有 /webjars/**
,都去 classpath:/META-INF/resources/webjars/ 找资源;
(2)"/**"
访问当前项目的任何资源,都去(静态资源的文件夹)找映射;
(3)静态资源文件夹下的所有index.html
页面;被"/**"
映射;
0x02.Spring Boot 模板引擎–thymeleaf
- 模板引擎(这里特指用于Web开发的模板引擎)是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的HTML文档。
- SpringBoot推荐使用Thymeleaf,它的优点是语法简单,功能强大。
- Thymeleaf 是 Web 和独立环境的现代服务器端 Java 模板引擎,能够处理HTML,XML,JavaScript,CSS 甚至纯文本。
1.导入thymeleaf:
- 在
pom.xml
中导入thymeleaf的坐标。
<properties>
<java.version>1.8</java.version>
<thymeleaf.version>3.0.11.RELEASE</thymeleaf.version>
<!-- 布局功能的支持程序 thymeleaf3主程序 layout2以上版本 -->
<!-- thymeleaf2 layout1-->
<thymeleaf-layout-dialect.version>2.2.2</thymeleaf-layout-dialect.version>
</properties>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
2.源码查看默认配置:
- 通过这段自动配置,我们可以发现,默认渲染的路径是
"classpath:/templates/"
,默认的后缀是.html
。 - 也就是说只要我们把HTML页面放在
classpath:/templates/
,thymeleaf就能自动渲染。
3.简单语法:
- 先导入thymeleaf的名称空间:
<html lang="en" xmlns:th="http://www.thymeleaf.org">
th:任意html属性
:来替换原生属性的值。
例如:
<div th:text="${atfwus}" th:id=${id}>
th:utext
:不转义字符。th:text
:转义字符。th:each
:遍历。th:if
,th:unless
,th:swith
,th:case
:判断。- 具体语法参考:https://raledong.gitbooks.io/using-thymeleaf/content/Chapter1/section1.1.html(中文版哦~)
0x03.Spring Boot 对Spring MVC的自动配置
1.查看Spring Boot官方的文档:
2.翻译及解释:
-
Inclusion of
ContentNegotiatingViewResolver
andBeanNameViewResolver
beans.- 自动配置了ViewResolver(视图解析器:根据方法的返回值得到视图对象,视图对象决定如何渲染。转发或者重定向)
- ContentNegotiatingViewResolver:用于组合所有的视图解析器;
- 我们可以自己给容器中添加一个视图解析器,ContentNegotiatingViewResolver会自动的将其组合进来;
-
Support for serving static resources, including support for WebJars (see below).
- 静态资源文件夹路径以及webjars。
-
Automatic registration of Converter, GenericConverter, Formatter beans.
- 自动注册了 of
Converter
,GenericConverter
,Formatter
beans. - Converter:转换器; 类型转换使用Converter。
Formatter
格式化器;- 如果自己添加的格式化器转换器,我们只需要放在容器中即可。
- 自动注册了 of
-
Support for
HttpMessageConverters
(see below).HttpMessageConverter
:SpringMVC用来转换Http请求和响应的;HttpMessageConverters
是从容器中确定;获取所有的HttpMessageConverter
;- 如果自己给容器中添加HttpMessageConverter,只需要将自己的组件注册容器中。
-
Automatic registration of MessageCodesResolver (see below).
- 自动注册了MessageCodesResolver。
- 定义错误代码生成规则
-
Static
index.html
support.- 静态首页访问。
-
Custom
Favicon
support (see below). favicon.ico- 自定义图标。
-
Automatic use of a
ConfigurableWebBindingInitializer
bean (see below).- 自动配置了
ConfigurableWebBindingInitializer
。
- 自动配置了
3.修改SpringBoot的默认配置:
- SpringBoot自动配置的原理:在自动配置很多组件的时候,先看容器中有没有用户自己配置的(@Bean、@Component)如果有就用用户配置的,如果没有,才自动配置;如果有些组件可以有多个(ViewResolver)将用户配置的和自己默认的组合起来;
- xxxConfigurer能够帮助我们进行扩展配置。
- xxxCustomizer能够帮助我们进行定制配置。
4.具体扩展Spring MVC:
- 如果您想保留Spring Boot MVC特性,并且只想添加额外的MVC配置(拦截器、格式化器、视图控制器等),那么可以添加自己的
@configuration
注解并继承WebMvcConfigurerAdapter
类,但不能使用@EnableWebMvc
。如果希望提供RequestMappingHandlerMapping
、RequestMappingHandlerAdapter
或ExceptionHandlerExceptionResolver
的自定义实例,则可以声明提供此类组件的WebMVCregistrationAdapte
r实例。 - 也就是说,如果我们要对Spring MVC进行拓展,只需要加上
@configuration
注解并继承WebMvcConfigurerAdapter
类就可以了。
例如:
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry){
registry.addViewController("/save").setViewName("success");
}
}
- 原理探究:
- 在自动配置类中导入了一个
EnableWebMvcConfiguration
配置类。
- 这个类又继承了一个
DelegatingWebMvcConfiguration
类,
- 在这里获取了容器中的配置。
-
我们找来一个实现的类查看一下:
-
我们可以发现,它实际上调用了所有的配置类。
-Spring Boot会将容器中所有的WebMvcConfigurer一起调用,SpringMVC的自动配置和我们的扩展配置都会起作用。
5.完全接管Spring MVC:
- 如果您想完全接管Spring MVC,可以添加自己的
@Configuration
,并用@EnableWebMvc
进行注释。 - 完全接管指的是,不需要SpringBoot对SpringMVC的自动配置,所有都是我们自己配置;所有的SpringMVC的自动配置全部失效。
- 原理探究:一直追踪这个注解
- 导入了一个配置类
DelegatingWebMvcConfiguration
。
- 这个类又继承了
WebMvcConfigurationSupport
类。
- 重点来了,在自动配置类
WebMvcAutoConfiguration
中,发现了下列这个注解。
- 我们就能够知道,如果使用了
@EnableWebMvc
,那么所有的自动配置将会失效。
ATFWUS --Writing By 2020–04-28