1. 文件类型
1.1 Properties
同以前的 properties 用法
1.2 yaml
1.2.1 简介
YAML 是 “YAML Ain’t Markup Language”(YAML 不是一种标记语言)的递归缩写。在开发这种语言时,YAML 的意思其实是:“Yet Another Markup Language”(仍是一种标记语言)
非常适合用来做以数据为中序的配置文件。
在 IDEA 中 xxx.yaml 也可以直接写为 xxx.yml
1.2.2 基本语法
- kay:value;kv 之间有空格
- 大小写敏感
- 使用缩进表示层级关系
- 缩进的空格数不重要,只要相同层级的元素左对齐即可
- “#” 表示注释
- “与” 表示字符串内容会被 转义/不转义
- 例如:
"zhangsan \n 李四"
- 双引号不会转义,\n 将作为换行输出
- 例如:
'zhangsan \n 李四'
- 单引号会转义,\n 将作为字符串输出
1.2.3 数据类型
- 字面量:单个的、不可再分的值。例如:date、boolean、string、number、null
k: v
- 对象:键值对的集合。map、hash、set、object
行内写法:k: {k1:v1,k2:v2,k3:v3} # 或 k: k1: v1 k2: v2 k3: v3
- 数组:一组按次序排列的值。array、list、queue
行内写法:k: [v1,v2,v3] # 或者 k: - v1 - v2 - v3
1.2.4 示例
person: name: zhangsan boss: true age: 21 birthdate: 2022/12/9 interests: - 篮球 - 足球 - 羽毛球 - 数字18 animal: [猫,狗] score: english: 80 math: 90 salarys: [8822,1290] pet: name: 旺旺 weight: 99.1 allpets: sick: - {name: 小蓝,weight: 92} - name: 小红 weight: 80 - name: 小黑 weight: 89 health: [{name: 小花,weight:90},{name: 小白,weight: 88}]
1.2.5 配置提示
- 当需要配置提示时,SpringBoot 也有对应的依赖来解决这个问题,我们只需要引入坐标即可。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency> <!--######################### 插件 ###############################--> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <!-- 在打包时,防止 SpringBoot 加载过多的类 --> <configuration> <excludes> <exclude> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> </exclude> </excludes> </configuration> </plugin> </plugins> </build>
2. SpringMVC 自动配置预览
SpringBoot 的自动配置基于 SpringMVC ,所以大多数场景我们都无需自定义配置
SpringBoot 的自动化配置包括了以下这些默认配置:
- 内容协商视图解析器和 BeanName 视图解析器
- 静态资源配置(包括 webjars)
- 自动化注册
Converter
,GenerIcConverter
,Formatter
- 支持
HttpMessageConverters
- 自动注册
MessageCodeResolver
(国际化用) - 静态
index.html
页支持 - 自定义每个网站的小图标
- 自动使用
ConfigurableWebBindingInitializer
(DataBinder 负责将请求数据绑定到 JavaBean 上)
如果想要自动化配置,那么 SpringBoot 官方也给出了以下几样建议
- 不用
@EnableWebMvc
注解。使用@Configuraion + @WebMvcConfigurer
自定义规则 - 声明
WebMvcRegistrations
改变默认底层组件 - 使用
@EnableWebMvc+@Configuration+DelegatingWebMvcConfiguration
全面接管SpringMVC
3. 简单功能分析
3.1 静态资源访问
3.1.1 静态资源目录:
只要静态资源放在类路径下: /static
(or public
or /resources
or META-INF/resources
)
访问:当前项目根路径/ + 静态资源路径
**原理:**静态映射 /**
。
请求进来,先去找 Controller 看能不能处理。
- 不能处理的所有请求又都交给静态资源处理器。
- 当静态资源处理器也无法处理,那么就找到 404
改变默认的静态资源路径:
spring: resources: static-locations: [ classpath: /haha/]
3.1.2 静态资源访问前缀
默认无前缀
spring: mvc: static-path-pattern: /res/**
经过设置后,变成了:当前项目 + static-path-pattern + 静态资源名 = 静态资源文件夹下查找
例子:
- 没配置前缀前:当前项目根路径/xxx.jpg 即可访问
- 配置上述前缀后:当前项目根路径/res/xxx.jpg 才能访问
3.1.3 webjar
springboot 支持 webjar;
3.1.3.1 webjar 简略介绍:
WebJars 是打包成 JAR(Java Archive)文件的客户端Web库(例如jQuery和Bootstrap)。
- 显式轻松地管理基于 JVM 的 Web 应用程序中的客户端依赖项
- 使用基于 JVM 的构建工具(例如 Maven、Gradle、sbt 等)下载客户端依赖项
- 了解您正在使用的客户端依赖项
- 传递依赖项通过 RequireJS 自动解析和选择性加载
- 部署在 Maven Central 上
3.1.3.2 使用:
官网:WebJars - Web Libraries in Jars
直接复制官网中的坐标粘贴至项目的 pom.xml 即可。
<dependency> <groupId>org.webjars.npm</groupId> <artifactId>jquery</artifactId> <version>3.6.0</version> </dependency>
如果要访问 webjar 为我们提供的 jar 包,那么访问需要加上前缀 webjar 再访问 webjar 中的插件
示例:/webjars/jquery/3.6.0/dist/jquery.js,后面地址要按照依赖的包路径填写
3.2 欢迎页支持
- 静态资源路径下生成 index.html
- 可以配置静态资源路径
- 但是不可以配置静态资源的访问前缀。否则导致 index.html 不能被默认访问
- controller 能处理 /index 请求
3.3 自定义 Favicon
跟欢迎页一样,不可以配置静态资源的访问前缀,否则会导致自定义图标失效
**使用:**将 favicon.ico 图标放在静态资源目录下即可。名称不可变
4. 静态资源配置原理
- SpringBoot 启动默认加载 xxxAutoConfiguration 类(自动配置类)
- SpringMVC 功能的自动配置类:WebMvcAutoConfiguration,生效
@AutoConfiguration( after = {DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class} ) @ConditionalOnWebApplication( type = Type.SERVLET ) @ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class}) @ConditionalOnMissingBean({WebMvcConfigurationSupport.class}) @AutoConfigureOrder(-2147483638) public class WebMvcAutoConfiguration {}
- 给容器中配置了什么?
@Configuration( proxyBeanMethods = false ) @Import({WebMvcAutoConfiguration.EnableWebMvcConfiguration.class}) @EnableConfigurationProperties({WebMvcProperties.class, WebProperties.class}) @Order(0) public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer, ServletContextAware {}
- 配置文件的相关属性和 xxx 进行了绑定。
- WebMvcProperties.class=“spring.mvc”
- WebProperties=“spring.web”
4.1 配置类只有一个有参构造器
- 有参构造器所有的参数的值都会从容器中绑定
- 参数说明:
- WebProperties webProperties:绑定 WebMvcProperties.class=“spring.mvc”
- WebMvcProperties mvcProperties:绑定 WebProperties=“spring.web”
- ListableBeanFactory beanFactory:获取 Spring 的 Bean 工厂
- ObjectProvider<HttpMessageConverters> messageConvertersProvider:找到所有的 HttpMessageConverters
- ObjectProvider<WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider:找到 资源处理器的自定义器
- ObjectProvider<DispatcherServletPath> dispatcherServletPath:调度程序的 Servlet 路径
- ObjectProvider<ServletRegistrationBean<?>> servletRegistrations:给应用注册 Servlet、Filter
public WebMvcAutoConfigurationAdapter(WebProperties webProperties, WebMvcProperties mvcProperties, ListableBeanFactory beanFactory, ObjectProvider<HttpMessageConverters> messageConvertersProvider, ObjectProvider<WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider, ObjectProvider<DispatcherServletPath> dispatcherServletPath, ObjectProvider<ServletRegistrationBean<?>> 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(); }
4.2 资源处理的默认规则
public void addResourceHandlers(ResourceHandlerRegistry registry) { // 获取静态资源的 add-mappings 属性,如果为false,那么所有的静态资源都被禁用了 if (!this.resourceProperties.isAddMappings()) { logger.debug("Default resource handling disabled"); } else { // 配置 webjars 的默认路径 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}); } }); } }
我们可以配置 resouce 中的 add-mappings 属性,如果值是 false ,静态资源都将不可访问
spring: web: resources: add-mappings: false
默认 静态资源 的配置路径
public static class Resources { private static final String[] CLASSPATH_RESOURCE_LOCATIONS = new String[]{"classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/"}; private String[] staticLocations; private boolean addMappings; private boolean customized; private final WebProperties.Resources.Chain chain; private final WebProperties.Resources.Cache cache; public Resources() { this.staticLocations = CLASSPATH_RESOURCE_LOCATIONS; this.addMappings = true; this.customized = false; this.chain = new WebProperties.Resources.Chain(); this.cache = new WebProperties.Resources.Cache(); } public String[] getStaticLocations() { // 返回默认路径 return this.staticLocations; }
4.3 欢迎页的处理规则
// HandlerMapping:处理映射,保存了每一个 Handler 能处理哪些请求 @Bean public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext, FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) { 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(TemplateAvailabilityProviders templateAvailabilityProviders, ApplicationContext applicationContext, Resource welcomePage, String staticPathPattern) { // 要用欢迎页功能,路径必须是 /** if (welcomePage != null && "/**".equals(staticPathPattern)) { logger.info("Adding welcome page: " + welcomePage); this.setRootViewName("forward:index.html"); } else if (this.welcomeTemplateExists(templateAvailabilityProviders, applicationContext)) { //调用 Controller /index logger.info("Adding welcome page template: index"); this.setRootViewName("index"); } }
4.4 favicon(项目图标)
与欢迎页面一样,默认是 /**
,如果没有将会在控制器中找 /favicon.ico
路径
5. ❤️👌SpringBoot 专栏前文回顾
6. 💕👉 其他好文推荐
- 还不了解Git分布式版本控制器?本文将带你全面了解并掌握
- 带你认识Maven的依赖、继承和聚合都是什么!有什么用?
- 2-3树思想与红黑树的实现与基本原理
- 全网最全!ElasticSearch8.7 搭配 SpringDataElasticSearch5.1 的使用
- 全面深入Java GC!!带你完全了解 GC垃圾回收机制!!
- 全面了解Java的内存模型(JMM)!详细清晰!
- 在JVM中,类是如何被加载的呢?本篇文章就带你认识类加载的一套流程!
- 带你了解Go语言的判断语句、切片和映射表!!
- (Java并发编程—JUC)带你重新认识进程与线程!!让你深层次了解线程运行的睡眠与打断!!
- JUC:从JMM内存模型的角度来分析CAS并发性问题
- 常见的设计模式概念分析与多把锁使用场景!!理解线程状态转换条件!带你深入JUC!!
- JUC:共享问题解决与synchronized对象锁分析!