1. SpringBoot 应该如何编写2. Lombok常用注解3. SpringBoot的 dev-tools开发者工具4. Spring Initializr(Spring 初始化器)5. yaml
5.1 什么是yaml5.2 yaml的基本语法5.3 yaml的使用5.4 yaml的单双引号5.5 在Idea中,自己配置的yaml,想要有提示效果(自定义类绑定的配置提示) 6. web场景 静态资源规则与定制化
6.1 官方对静态资源相关的解释目录位置6.2 静态资源目录6.3 配置静态访问url的前缀6.4 支持 WebJars 的使用 7. web场景 欢迎页与favicon功能
7.1 欢迎页7.2 favicon图标 8. web场景 静态资源的配置原理
8.1 自动配置SpringMVC原理8.2 SpringMvc资源处理的默认规则
8.2.1 spring.web.resources.add-mappings=false 禁用静态资源规则8.2.2 spring.web.resources.add-mappings=true(默认) 启动静态资源规则 的一些源码分析 8.3 SpringBoot的欢迎页的处理规则源码
1. SpringBoot 应该如何编写去官方对应的springboot版本,引入场景依赖,也就是starter场景器。
https://spring.io/projects/spring-boot#learn
查看自动配置了哪些内容:
可以在application.properties中,配置debug=true,看起自动配置报告。Negative(否定的,消极的)是不生效的自动配置。Positive(乐观的,积极的)是生效的自动配置。
查看哪些需要修改的配置项:
第一种方式:参考官方的配置项修改。
第二种方式:分析源码,xxxAutoConfiguration类 , xxxProperties类。
按照所需,自定义加入或者替换组件:
@Bean,@Component等等
按照所需,自己创建自定义器:
自定义器格式:xxxCustomizer 2. Lombok常用注解
@AllArgsConstructor注解:定义所有参数的构造器。
@NoArgsConstructor注解:无参构造器。
@Data注解:生成get和set方法(在没有@AllArgsConstructor和@NoArgsConstructor默认生成无参构造器。)
@ToString注解:重写toString()方法。
@EqualsAndHashCode注解:重写equals和hashCode方法。
@Slf4j注解:自动给类中注入一个log属性。
先去对应版本的官方导入响应的dev-tools开发依赖。
dev-tools开发者工具作用:就是重新加载静态或代码文件。
当修改静态文件后ctrl+F9,会帮我们加载上面,不需要重新加载。当我们修改了代码后,我们只需要ctrl+F9就会重新加载整个程序。
dev-tools是Restart,就是重新启动。
如果想要reload,重新加载(所谓的热部署,热加载)。可以去官方看推荐。
就是通过idea来创建SpringBoot项目,很方便!
结构如下:
SpringBoot除了支持application.properties作为配置文件外,还有另一种配置方式yaml。
yaml非常适合来做以数据为中心的配置文件。
5.2 yaml的基本语法语法格式:
# key和value之间有冒号和空格。 key: value
大小写敏感。
使用缩进表示层级关系。
缩进不允许使用tab,只允许空格。缩进的空格数不重要,只要相同层级的元素左对齐即可。
#号,表示注释。
字符串无序加引号,如果要加,‘单引号’ 和 "双引号"表示字符串内容 会被转义/不转义。
写法如下:
创建yaml文件的时候,可以使 .yml 或 .yaml末尾。
创建一个实体类,通过yaml给实体类赋值:
使用@Component和@ConfigurationProperties()注解。
package com.itholmes.boot.boot01helloworld2.bean;
import lombok.Data;
import lombok.ToString;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
@Component
@ConfigurationProperties(prefix = "person")
@ToString
@Data
public class Person {
private String userName;
private Boolean boss;
private Date birth;
private Integer age;
private String[] interests;
private List animal;
private Map score;
private Set salarys;
private Pet pet;
private Map> allPets;
}
对应上面实体类的一些yaml格式的属性配置:
person:
userName: zhangsan
boss: true
birth: 2019/12/9
age: 18
# 数组方式一:行内写法
# interests: [篮球,足球]
# 数组方式二:
interests:
- 篮球
- 足球
# list写法和数组写法相同:
animal: [阿猫,阿狗]
# map类型的写法方式一:
# score:
# english: 80
# math: 90
score: {english:80,math:90} # 这里就不需要写 ": " 因为是json形式。
# set写法和数组写法也是相同的
salarys:
- 9999.98
- 9999999
# 对于引用对象类型的属性设置,缩进就可以了。
pet:
name: 阿狗
weight: 99.99
# Map> allPets; 对于这种复杂变量类型的。
allPets:
sick:
- {name: 阿狗,weight: 99.99}
- name: 阿猫
weight: 88.88
- name: 阿六
weight: 77.77
health: [{name: 阿狗,weight: 99.99},{name: 阿狗,weight: 99.99}]
# 以后配置文件,通过yaml也是很方便的。
#spring:
# banner:
# charset:
# cache:
# cache-names:
5.4 yaml的单双引号
无论单引号还是双引号,都是表示字符串的。但是也有不同点!
那就是双引号不会自动将转义字符进行转义, 单引号会将转义字符转义成为普通字符串!转义字符就是 " / " 。像/n,本来就是换行的意思,一旦写成//n那就不是换行了就是普通的字符串 " /n "。单引号效果:
双引号效果:
5.5 在Idea中,自己配置的yaml,想要有提示效果(自定义类绑定的配置提示)
在Idea中,自己配置的yaml,想要有提示效果,可以添加一个标注处理器( Configuring the Annotation Processor,英文直译就是配置标注处理器,不要一直以为是注解。) , 见下图:
先打开官方对应SpringBoot版本的参考文档:
找到Configuration the Annotation Processor:
按照官方要求,导入对应的configuration-processor依赖:
org.springframework.boot spring-boot-configuration-processor true
之后,就不会变红了,提示你重新启动一下SpringBoot。
此外,因为这个spring-boot-configuration-processor包,是为了方便我们开发人员使用的,所以打包,发布的时候,就不要再加上!没必要添加没用的jar包。
官方文档关于web场景的内容如下图:
官方静态资源的章节,如下图:
官方的原话是/static (or /public or /resources or /meta-INF/resources) in the classpath or from the root of the ServletContext.
**默认静态资源的存放位置是类路径下:有/static (or /public or /resources or /meta-INF/resources) **
后台也可以自定义静态资源配置目录:
spring:
mvc:
# 配置静态访问url的前缀。
static-path-pattern: /res/**
web:
resources:
# 配置后台静态资源路径位置。
static-locations: classpath:/haha/
这样,我们就只能在/haha这个目录下面查找静态资源了。
如果controller映射的路径和静态资源的名字重名的话,是怎样?
流程如下:
请求进来,先去找Controller看能不能处理,能不能映射到mapping;不能处理的所有请求又都交给静态资源处理器处理,如果静态资源也找不到对应路径内容,那么就是返回404。 6.3 配置静态访问url的前缀
静态映射的默认路径是: " /** "。表示当前下的所有包下的资源路径。并且没有前缀。
默认静态资源是无前缀的:
而我们配置前缀url的目的是,方便我们的拦截器或者过滤器的一些操作,如下:
spring:
mvc:
static-path-pattern: /res/**
这样,我们想要请求静态资源,必须携带/res的前缀路径。
WebJars官方
WebJars就是将前端的一些js,css等等文件,也全都做成了依赖。
如果是maven,同样也就可以直接在pom上面导入依赖就可以了。
使用引入的js路径,因为该包里面也有meta-INF/resources,对应了默认的静态资源引入路径:
官方给出两种欢迎页的方式:
静态资源路径下,index.html页面:
可以配置静态资源路径。但是不可以配置静态资源的访问前缀,否则导致index.html不能被默认访问。这算是一个小bug点。
spring:
mvc:
# 不能配置,会影响index.html的默认访问。
static-path-pattern: /res/**
7.2 favicon图标
只需要将favicon.ico图片放到,静态资源规定的路径下就可以了。
同样favicon.ico也是会被静态资源访问前缀影响!
spring:
mvc:
# 不能配置,也会影响到favicon.ico的配置。
static-path-pattern: /res/**
8. web场景 静态资源的配置原理
8.1 自动配置SpringMVC原理
SpringBoot启动默认加载一些列的xxxAutoConfiguration自动配置类。
其中SpringMVC功能的自动配置类,对应WebMvcAutoConfiguration。
对应的有参构造器所有参数的值都会从容器中确定:
//webProperties获取和spring.web绑定的所有值的对象,在构造器里面它会把配置信息给到resourceProperties变量中。 //mvcProperties获取和spring.mvc绑定的所有值的对象。 //ListableBeanFactory beanFactory是Spring的bean工厂 //HttpmessageConverters找到所有的HttpmessageConverters //resourceHandlerRegistrationCustomizerProvider找到资源处理器的自定义器。 //dispatcherServletPath是dispatcherServlet的路径。 //servletRegistrations给应用注册Servlet,Filter等 public WebMvcAutoConfigurationAdapter( WebProperties webProperties, WebMvcProperties mvcProperties, ListableBeanFactory beanFactory, ObjectProvider8.2 SpringMvc资源处理的默认规则 8.2.1 spring.web.resources.add-mappings=false 禁用静态资源规则messageConvertersProvider, ObjectProvider resourceHandlerRegistrationCustomizerProvider, ObjectProvider dispatcherServletPath, ObjectProvider > servletRegistrations) { this.resourceProperties = webProperties.getResources(); this.mvcProperties = mvcProperties; this.beanFactory = beanFactory; this.messageConvertersProvider = messageConvertersProvider; this.resourceHandlerRegistrationCustomizer = (WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer)resourceHandlerRegistrationCustomizerProvider.getIfAvailable(); this.dispatcherServletPath = dispatcherServletPath; this.servletRegistrations = servletRegistrations; this.mvcProperties.checkConfiguration(); }
在WebMvcAutoConfiguration类中,有一个addResourceHandlers方法,对于静态资源自动处理都是经过该方法。
!this.resourceProperties.isAddMappings()是判断是否禁用静态资源规则。
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
} else {
this.addResourceHandler(registry, "/webjars/**", "classpath:/meta-INF/resources/webjars/");
this.addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
registration.addResourceLocations(this.resourceProperties.getStaticLocations());
if (this.servletContext != null) {
ServletContextResource resource = new ServletContextResource(this.servletContext, "/");
registration.addResourceLocations(new Resource[]{resource});
}
});
}
}
注意前面有一个取反操作: !this.resourceProperties.isAddMappings() ,我们进入该方法所在的源码查看。
也就是当我们设置spring.web.resources.add-mappings为false(这里用的yaml形式。),就会禁用了静态资源规则。
spring:
web:
resources:
add-mappings: true # 表示静态资源会被禁用掉!
8.2.2 spring.web.resources.add-mappings=true(默认) 启动静态资源规则 的一些源码分析
对应缓存设置时间的源码分析:
对于能够默认访问webjars静态资源的源码分析原因:
配置访问静态资源url前缀的源码分析:
spring.web.resources.static-locations,配置后台静态资源存储访问路径的源码分析:
也是在WebMvcAutoConfiguration类中静态类里面的welcomePageHandlerMapping方法:
//在SpringMvc中有一个HandlerMapping:处理器映射。保存了每一个Handler能处理那些请求。
@Bean
public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext, FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
//这里有一个WelcomePageHandlerMapping对象,给他传入了很多参数,其中就包括this.mvcProperties.getStaticPathPattern()参数。
WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(new TemplateAvailabilityProviders(applicationContext), applicationContext, this.getWelcomePage(), this.mvcProperties.getStaticPathPattern());
welcomePageHandlerMapping.setInterceptors(this.getInterceptors(mvcConversionService, mvcResourceUrlProvider));
welcomePageHandlerMapping.setCorsConfigurations(this.getCorsConfigurations());
return welcomePageHandlerMapping;
}
进入WelcomePageHandlerMapping对象构造方法源码分析:
通过源码来看,也解释了为什么自定义设置了staticPathPattern(请求资源路径前缀),就不能默认访问index.html页面了。并且默认还是走方式二的template的index的handler路径(controller路径)。
WelcomePageHandlerMapping(TemplateAvailabilityProviders templateAvailabilityProviders, ApplicationContext applicationContext, Resource welcomePage, String staticPathPattern) {
//welcomePage欢迎页存在 ,并且staticPathPattern路径是"/**"就可以走方式一(static静态欢迎页):index.html路径。
if (welcomePage != null && "/**".equals(staticPathPattern)) {
logger.info("Adding welcome page: " + welcomePage);
this.setRootViewName("forward:index.html");
} else if (this.welcomeTemplateExists(templateAvailabilityProviders, applicationContext)) {
//调用Controller(handler) /index
logger.info("Adding welcome page template: index");
this.setRootViewName("index");
}
}



