【SpringBoot(二)】带你认识Yaml配置文件类型、SpringMVC的资源访问路径 和 静态资源配置的原理!

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
应用实时监控服务-可观测链路OpenTelemetry版,每月50GB免费额度
可观测可视化 Grafana 版,10个用户账号 1个月
简介: SpringBoot专栏第二章,从本章开始正式进入SpringBoot的WEB阶段开发,本章先带你认识yaml配置文件和资源的路径配置原理,以方便在后面的文章中打下基础

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)
  • 自动化注册 ConverterGenerIcConverterFormatter
  • 支持 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. 💕👉 其他好文推荐

目录
相关文章
|
9月前
|
存储 Java 文件存储
微服务——SpringBoot使用归纳——Spring Boot使用slf4j进行日志记录—— logback.xml 配置文件解析
本文解析了 `logback.xml` 配置文件的详细内容,包括日志输出格式、存储路径、控制台输出及日志级别等关键配置。通过定义 `LOG_PATTERN` 和 `FILE_PATH`,设置日志格式与存储路径;利用 `&lt;appender&gt;` 节点配置控制台和文件输出,支持日志滚动策略(如文件大小限制和保存时长);最后通过 `&lt;logger&gt;` 和 `&lt;root&gt;` 定义日志级别与输出方式。此配置适用于精细化管理日志输出,满足不同场景需求。
2167 1
|
5月前
|
人工智能 JSON Java
Spring Boot 如何接收并处理不确定类型的请求参数?
在 Spring Boot 中,当需要处理结构不确定的 JSON 数据时,可以使用 `Map` 类型灵活接收键值对数据。对于更复杂的场景,可通过 Jackson 注解支持多态类型、自定义反序列化器,或在接收后动态解析 JSON 数据,提升处理灵活性和扩展性。
165 0
|
9月前
|
Java 数据库 微服务
微服务——SpringBoot使用归纳——Spring Boot中的项目属性配置——指定项目配置文件
在实际项目中,开发环境和生产环境的配置往往不同。为简化配置切换,可通过创建 `application-dev.yml` 和 `application-pro.yml` 分别管理开发与生产环境配置,如设置不同端口(8001/8002)。在 `application.yml` 中使用 `spring.profiles.active` 指定加载的配置文件,实现环境快速切换。本节还介绍了通过配置类读取参数的方法,适用于微服务场景,提升代码可维护性。课程源码可从 [Gitee](https://gitee.com/eson15/springboot_study) 下载。
366 0
|
存储 前端开发 JavaScript
springboot中路径默认配置与重定向/转发所存在的域对象
Spring Boot 提供了简便的路径默认配置和强大的重定向/转发机制,通过合理使用这些功能,可以实现灵活的请求处理和数据传递。理解并掌握不同域对象的生命周期和使用场景,是构建高效、健壮 Web 应用的关键。通过上述详细介绍和示例,相信读者能够更好地应用这些知识,优化自己的 Spring Boot 应用。
604 3
|
分布式计算 关系型数据库 MySQL
SpringBoot项目中mysql字段映射使用JSONObject和JSONArray类型
SpringBoot项目中mysql字段映射使用JSONObject和JSONArray类型 图像处理 光通信 分布式计算 算法语言 信息技术 计算机应用
265 8
|
Java 数据库连接 数据库
springboot启动配置文件-bootstrap.yml常用基本配置
以上是一些常用的基本配置项,在实际应用中可能会根据需求有所变化。通过合理配置 `bootstrap.yml`文件,可以确保应用程序在启动阶段加载正确的配置,并顺利启动运行。
1630 2
springboot 获取访问接口的请求的IP地址
springboot 获取访问接口的请求的IP地址
3183 0
|
2月前
|
JavaScript Java 关系型数据库
基于springboot的项目管理系统
本文探讨项目管理系统在现代企业中的应用与实现,分析其研究背景、意义及现状,阐述基于SSM、Java、MySQL和Vue等技术构建系统的关键方法,展现其在提升管理效率、协同水平与风险管控方面的价值。
|
2月前
|
搜索推荐 JavaScript Java
基于springboot的儿童家长教育能力提升学习系统
本系统聚焦儿童家长教育能力提升,针对家庭教育中理念混乱、时间不足、个性化服务缺失等问题,构建科学、系统、个性化的在线学习平台。融合Spring Boot、Vue等先进技术,整合优质教育资源,提供高效便捷的学习路径,助力家长掌握科学育儿方法,促进儿童全面健康发展,推动家庭和谐与社会进步。