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

本文涉及的产品
应用实时监控服务-可观测链路OpenTelemetry版,每月50GB免费额度
可观测可视化 Grafana 版,10个用户账号 1个月
应用实时监控服务-应用监控,每月50GB免费额度
简介: 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. 💕👉 其他好文推荐

目录
相关文章
|
11天前
|
存储 关系型数据库 分布式数据库
PostgreSQL 18 发布,快来 PolarDB 尝鲜!
PostgreSQL 18 发布,PolarDB for PostgreSQL 全面兼容。新版本支持异步I/O、UUIDv7、虚拟生成列、逻辑复制增强及OAuth认证,显著提升性能与安全。PolarDB-PG 18 支持存算分离架构,融合海量弹性存储与极致计算性能,搭配丰富插件生态,为企业提供高效、稳定、灵活的云数据库解决方案,助力企业数字化转型如虎添翼!
|
10天前
|
存储 人工智能 搜索推荐
终身学习型智能体
当前人工智能前沿研究的一个重要方向:构建能够自主学习、调用工具、积累经验的小型智能体(Agent)。 我们可以称这种系统为“终身学习型智能体”或“自适应认知代理”。它的设计理念就是: 不靠庞大的内置知识取胜,而是依靠高效的推理能力 + 动态获取知识的能力 + 经验积累机制。
356 131
|
10天前
|
存储 人工智能 Java
AI 超级智能体全栈项目阶段二:Prompt 优化技巧与学术分析 AI 应用开发实现上下文联系多轮对话
本文讲解 Prompt 基本概念与 10 个优化技巧,结合学术分析 AI 应用的需求分析、设计方案,介绍 Spring AI 中 ChatClient 及 Advisors 的使用。
443 131
AI 超级智能体全栈项目阶段二:Prompt 优化技巧与学术分析 AI 应用开发实现上下文联系多轮对话
|
4天前
|
存储 安全 前端开发
如何将加密和解密函数应用到实际项目中?
如何将加密和解密函数应用到实际项目中?
206 138
|
10天前
|
人工智能 Java API
AI 超级智能体全栈项目阶段一:AI大模型概述、选型、项目初始化以及基于阿里云灵积模型 Qwen-Plus实现模型接入四种方式(SDK/HTTP/SpringAI/langchain4j)
本文介绍AI大模型的核心概念、分类及开发者学习路径,重点讲解如何选择与接入大模型。项目基于Spring Boot,使用阿里云灵积模型(Qwen-Plus),对比SDK、HTTP、Spring AI和LangChain4j四种接入方式,助力开发者高效构建AI应用。
405 122
AI 超级智能体全栈项目阶段一:AI大模型概述、选型、项目初始化以及基于阿里云灵积模型 Qwen-Plus实现模型接入四种方式(SDK/HTTP/SpringAI/langchain4j)
|
4天前
|
存储 JSON 安全
加密和解密函数的具体实现代码
加密和解密函数的具体实现代码
204 136
|
22天前
|
弹性计算 关系型数据库 微服务
基于 Docker 与 Kubernetes(K3s)的微服务:阿里云生产环境扩容实践
在微服务架构中,如何实现“稳定扩容”与“成本可控”是企业面临的核心挑战。本文结合 Python FastAPI 微服务实战,详解如何基于阿里云基础设施,利用 Docker 封装服务、K3s 实现容器编排,构建生产级微服务架构。内容涵盖容器构建、集群部署、自动扩缩容、可观测性等关键环节,适配阿里云资源特性与服务生态,助力企业打造低成本、高可靠、易扩展的微服务解决方案。
1363 8
|
9天前
|
监控 JavaScript Java
基于大模型技术的反欺诈知识问答系统
随着互联网与金融科技发展,网络欺诈频发,构建高效反欺诈平台成为迫切需求。本文基于Java、Vue.js、Spring Boot与MySQL技术,设计实现集欺诈识别、宣传教育、用户互动于一体的反欺诈系统,提升公众防范意识,助力企业合规与用户权益保护。

热门文章

最新文章