静态资源
关于静态资源的规则配置,有多种方式可以达成这种目标。
SpringBoot 默认的自动配置位置:*.autoconfigure.web.servlet.WebMvcAutoConfiguration.java 其中的 addResourceHandlers 方法;
可以通过配置文件来配置一些有关于静态资源的配置,配置前缀:spring.resource
@ConfigurationProperties(prefix = "spring.resources", ignoreUnknownFields = false)
public class ResourceProperties {
// 。。。。。。
}
默认两种方式,一种是 webjars,另外一种是默认目录寻找静态资源。
webjars 方式
以 jar 的方式,来导入前端的一些依赖库。
- 这种方式在 SpringBoot 有默认的寻址配置。
- MVC 自动配置路径:*.autoconfigure.web.servlet.WebMvcAutoConfiguration.java
- 其中有个方法:addResourceHandlers,就是配置了静态资源的规则
实际上,上面的默认规则是从 webjars/**
匹配到实际路径 META-INF/resources/webjars/**
如,可以通过 maven 来添加所需要的组件依赖
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.5.1</version>
</dependency>
然后,尝试访问:http://localhost:8080/webjars/jquery/3.5.1/jquery.js,若是没有情况出现,就可以正常访问。
webjars 组件包,可以从 https://www.webjars.org/ 网站下载;
默认静态资源路径
访问网站的 /** 路径下的静态资源,默认会在以下几个路径下寻找:
classpath:/META-INF/resources/
classpath:/resources/
classpath:/static/
classpath:/public/
/
classpath:类路径下,体现在项目中目录,就是默认创建的 resources 目录下。
当然,可以通过在配置文件中设置。
默认首页
SpringBoot 中,设置首页的方法有多种多样,其中可以通过以下几种设置首页。
- 重写:addViewController 方法
- 重写:addResourceHandlers 方法
- 跳转
- 重定向
- 放在 /META-INF/resources/、/resources/、/static/、/public/ 会默认加载
addViewController
public class DefaultView extends WebMvcConfigurationSupport {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("forward:index.html");
registry.setOrder(Integer.MIN_VALUE);
super.addViewControllers(registry);
}
}
addResourceHandlers
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/templates/**")
.addResourceLocations("classpath:/templates/");
super.addResourceHandlers(registry);
}
默认 ico
将 favicon.ico 放置在类路径下的:resourcese、static、public、MATE_INFO/resources 几个位置即可,这些位置是 SpringBoot 默认寻找的目录,可以通过 spring.resources.static-locations 配置项修改寻找位置,这是要给数组元素。
模板引擎
主流的模板引擎:freemaker、thymeleaf;
jsp 已经淘汰,剩下的就是一些老项目在使用。
在 SpringBoot 项目中,推荐使用 Thymeleaf,同时也提供了相应的 starter 场景,使用很简单,只要引入相应 starter 即可。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
Thymeleaf 使用
该模板引擎本身有默认的配置,所以可以直接拆箱即用。
基础语法
在 HTML 标签上,添加 Thymeleaf 名称空间,方便提示语法;
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
// ......
</html>
thymeleaf 基础语法是从 th: 开头的,后面跟着特定名称。
作用在标签上,任意的属性都可以修改。
表达式
简单的表达式()
-
变量表达式:${…}
- 获取对象属性、调用对象方法
- 使用内置对象
- 使用内置工具对象 -
选择变量表达式:*{…}
- 功能上与 ${…} 重叠,在这基础上,增加了一个特性,如:
<div th:object="${session.user}"> <p>Name: <span th:text="*{firstName}">Sebastian</span>.</p> <p>Surname: <span th:text="*{lastName}">Pepper</span>.</p> <p>Nationality: <span th:text="*{nationality}">Saturn</span>.</p> </div> 相当于 ${…} 的: <div> <p>Name: <span th:text="${session.user.firstName}">Sebastian</span>.</p> <p>Surname: <span th:text="${session.user.lastName}">Pepper</span>.</p> <p>Nationality: <span th:text="${session.user.nationality}">Saturn</span>.</p> </div>
-
消息表达式:#{…}
- 获取国际化
-
链接URL表达式:@{…}
- 对链接产生作用,如示例:
<!-- 'http://localhost:8080/gtvg/order/details?orderId=3'--> <a href="details.html" th:href="@{http://localhost:8080/gtvg/order/details(orderId=${o.id})}">view</a> <!-- '/gtvg/order/details?orderId=3' --> <a href="details.html" th:href="@{/order/details(orderId=${o.id})}">view</a> <!-- '/gtvg/order/3/details' --> <a href="details.html" th:href="@{/order/{orderId}/details(orderId=${o.id})}">view</a>
- 多个参数可以用
,
分割:@{/order/process(execId=${execId},execType='FAST')}
-
片段表达式:~{…}
示例
${person.father.name}
${person['father']['name']}
${countriesByCode.ES}
${personsByName['Stephen Zucchini'].age}
${personsArray[0].name}
${person.createCompleteName()}
${person.createCompleteNameWithSeparator('-')}
字面量
- 文本:'one text', 'Another one!',…
- 整数:0 , 34 , 3.0 , 12.3 ,…
- 布尔:true , false
- null
- 常量标记:one , sometext , main ,…
文本操作
- 字符串连接:+
- 文字替换:|The name is $|
算术运算
- 二元操作符:+, -, *, /, %
- 负号(一元运算符):-
布尔操作
- 二元操作符:and , or
- 布尔否定(一元运算符):! , not
对比与等式运算
- 比较:>, <, >=, <=(gt, lt, ge, le)
- 等式运算符:==, !=(eq, ne)
条件运算符
- If-then:(if) ? (then)
- If-then-else:(if) ? (then) : (else)
- Default:(value) ?: (defaultvalue)
特殊的标记
- 无操作:_
属性优先级
WebMvc 自动配置解析
Spring Boot 提供了现成的自动配置,无需另外配置。
自动配置在 Spring 的默认设置之上添加了以下特性:
-
Inclusion of
ContentNegotiatingViewResolver
andBeanNameViewResolver
beans.ContentNegotiatingViewResolver
:组合全部试图解析器,定位到最适合的试图解析器来解析试图。由于该类会组合所有试图解析,所以自定义的试图解析器会被自动加载。- 该自动配置,会返回一个试图解析器,然后试图解析器会决定如何渲染试图,resolverViewName 重写该方法,可以定制解析逻辑。
/** 自定义试图解析器,会被 ContentNegotiatingViewResolver 自动组合。 通过打断点,可以从 DispatcherSerlvet 的 doDispatcher 方法中,查看所有的试图解析器 viewResolver。 */ @Bean public ViewResolver MyResolver() { return new MyResolver(); } public class MyResolver implements ViewResolver{ @Override public View resolveViewName(String viewName, Locale locale) throws Exception { return null; } }
-
支持为静态资源提供服务,包括支持WebJars (covered later in this document)).
-
Automatic registration of
Converter
,GenericConverter
, andFormatter
beans.- Converter:类型转换器
- Formatter:格式化器
/** 自定义格式化器 */ @Bean public FormattingConversionService MyFormatter() { return new MyFormatterConversionService(); } class MyFormatterConversionService extends FormattingConversionService { // ...... }
-
支持 HttpMessageConverters (covered later in this document).
-
Http 请求与响应之间的转换,比如说:对象转 JSON,JSON 转对象。
-
因为在容器中中所有的消息转换器都会被加载到列表中,所以同样可以自定义这类消息转换器,只要将其添加到容器中即可,例如:
@Bean public HttpMessageConverters customConverters() { HttpMessageConverter<?> additional = ... HttpMessageConverter<?> another = ... return new HttpMessageConverters(additional, another); }
-
-
自动注册
MessageCodesResolver
(covered later in this document).- 定义校验导致的错误提示规则
-
支持静态:index.html
-
支持自定义 favicon.ico (covered later in this document).
-
ConfigurableWebBindingInitializer
(covered later in this document).- Web 数据绑定,例如说:将请求的数据绑定到 JavaBean 中。
扩展自动配置
SpringBoot 对 SpringMVC 的自动配置的基础上,可以自定义扩展对 SpringMVC 的配置项,要做到这一点,只需要在一个普通类上加上:@Configuration 注解,然后是实现 WebMvcConfigurer 接口即可。
完成这一步,就可以对想要扩展的功能,重写相应的方法即可。
但是,需要注意一点,不需要 @EnableWebMvc,该注解是摒弃 SpringBoot 的自动配置的,交由用户全部自定义配置。
示例:
@SpringBootConfiguration
public class AdminConfiguration extends WebMvcConfigurationSupport {
@Override
protected void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/index").setViewName("index");
}
}
简单的,给项目中添加一个控制器。
原理
SpringBoot 在加载默认的 WebMvc 自动配置的时候,会同时加载一个内部类:WebMvcAutoConfigurationAdapter,主要作用是该类的上面有一个注解:@Import(EnableWebMvcConfiguration.class)。
@Configuration(proxyBeanMethods = false)
@Import(EnableWebMvcConfiguration.class)
@EnableConfigurationProperties({ WebMvcProperties.class, ResourceProperties.class })
@Order(0)
public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer {
// ......
}
这个内部类本身是一个配置类存在,所以会被 SpringBoot 扫描。
通过导入 EnableWebMvcConfiguration 这个组件,该组件继承了一个配置类:DelegatingWebMvcConfiguration,这个类有一个 setConfigurers 方法,该方法会将所有的配置都加载。
/**
EnableWebMvcConfiguration 类
*/
@Configuration(proxyBeanMethods = false)
public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware {
// ......
}
/**
DelegatingWebMvcConfiguration 类
*/
@Configuration(proxyBeanMethods = false)
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite();
@Autowired(required = false)
public void setConfigurers(List<WebMvcConfigurer> configurers) {
if (!CollectionUtils.isEmpty(configurers)) {
this.configurers.addWebMvcConfigurers(configurers);
}
}
// 这个类的所有方法,几乎都是对不同的组件添加所有配置。
}
自定义配置(摒弃 SpringBoot 默认配置)
在 SpringBoot 中,提到一点,可以对 SpringBoot 中 SpringMVC 的配置扩展。但是,不能作用 @EnableWebMvc。
给一个配置类加上这个注解:@EnableWebMvc,会触发 SpringBoot 中 SpringMVC 配置类的一个条件。
// ...... 省略
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
// ...... 省略
public class WebMvcAutoConfiguration {
// ......
}
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class):表示若是容器中没有 WebMvcConfigurer 这个类,那么该配置类才会生效。
而在 @EnableWebMvc 这个注解中,会导入一个组件:DelegatingWebMvcConfiguration,该组件的父类正是:WebMvcConfigurationSupport。
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {
}
所以,一旦加了 @EnableWebMvc,代表着所有的关于 SpringMVC 的配置都需要自己手动配置。
更改SpringBoot 默认自动配置
有两种方式:
- SpringBoot 会判断容器中是否已有相应的组件,通常这些组件来自于用户自定义。在这种情况下,SpringBoot 会使用用户自定义的组件,而不是加载默认的自动配置。
- 用户自定义配置的,如:@Bean,@Component,XML等等。
- SpringBoot 允许多个组件的时候,会加载所有满足条件的组件。
注意
WebMvcConfigurationAdapter 过期替代产品
- WebMvcConfigurationSupport 类:若是继承该类,代表着 SpringBoot 对 WebMVC 的自动配置全部摒弃。
- WebMvcConfigurer 接口(推荐)
扩展
- webjars 网站:https://www.webjars.org/
- WebMvc 自动配置参考:https://docs.spring.io/spring-boot/docs/2.2.5.RELEASE/reference/htmlsingle/#boot-features-spring-mvc-auto-configuration
Q.E.D.
Comments | 0 条评论