Spring、Spring Boot 与配置文件核心知识点详解

文章目录

    • [一、Spring、Spring Boot、Spring MVC 核心关系与区别](#一、Spring、Spring Boot、Spring MVC 核心关系与区别)
      • [1.1 Spring --- 企业级开发的基石](#1.1 Spring — 企业级开发的基石)
      • [1.2 Spring MVC --- Web 层子框架](#1.2 Spring MVC — Web 层子框架)
      • [1.3 Spring Boot --- 快速开发整合包](#1.3 Spring Boot — 快速开发整合包)
      • [1.4 三者关系总结](#1.4 三者关系总结)
    • 二、配置文件核心知识点
      • [2.1 配置文件的作用 --- 解决硬编码](#2.1 配置文件的作用 — 解决硬编码)
      • [2.2 三类配置文件与优先级](#2.2 三类配置文件与优先级)
      • [2.3 properties 配置详解](#2.3 properties 配置详解)
        • [2.3.1 基础语法](#2.3.1 基础语法)
        • [2.3.2 使用 @Value 读取配置](#2.3.2 使用 @Value 读取配置)
        • [2.3.3 properties 的核心缺点](#2.3.3 properties 的核心缺点)
      • [2.4 yml(YAML)配置详解](#2.4 yml(YAML)配置详解)
        • [2.4.1 基础语法](#2.4.1 基础语法)
        • [2.4.2 字符串单/双引号规则(易错点)](#2.4.2 字符串单/双引号规则(易错点))
        • [2.4.3 使用 @ConfigurationProperties 批量绑定](#2.4.3 使用 @ConfigurationProperties 批量绑定)
        • [2.4.4 yml 优缺点总结](#2.4.4 yml 优缺点总结)
    • 三、整体总结
      • [3.1 开发选型建议](#3.1 开发选型建议)
      • [3.2 依赖关系速记](#3.2 依赖关系速记)
      • [3.3 配置读取方式](#3.3 配置读取方式)
      • 全文总结
      • 核心知识点复盘
      • [常见问题 / 避坑指南](#常见问题 / 避坑指南)

本文基于 Spring Boot 项目实战代码,系统梳理 Spring 生态核心概念与配置文件使用技巧,适合 Spring 初学者系统学习及有经验的开发者复盘巩固。


一、Spring、Spring Boot、Spring MVC 核心关系与区别

对于刚接触 Spring 生态的开发者来说,Spring、Spring MVC、Spring Boot 这三个名词经常同时出现,很容易混淆。本节从定位和职责两个维度帮你理清三者的关系。

1.1 Spring --- 企业级开发的基石

Spring 是一个轻量级、一站式、模块化的企业级开发框架。 它的核心价值在于"管理对象及其依赖关系"------也就是我们常说的 IoC(控制反转)DI(依赖注入)

在真实的 Spring 项目中,你只需通过注解声明依赖关系,容器会自动完成对象的创建和注入。

Spring 的核心能力一览:

能力 说明
IoC / DI 管理对象的创建和依赖关系
AOP 面向切面编程,统一处理日志、事务等横切关注点
事务管理 声明式事务,简化数据库操作
数据访问 整合 JDBC、ORM 框架
Web 支持 提供 Spring MVC 子框架

Spring 的另一大优势是高开放性:不强制绑定全套组件,可以按需选用模块,也能无缝整合 Hibernate、Struts 等第三方框架。

1.2 Spring MVC --- Web 层子框架

Spring MVC 是 Spring 原生的 Web 子框架,专注于 Web 应用与 RESTful 接口开发。

它依托 Spring 内核构建,天然与 Spring 容器无缝集成。核心能力包括:

  • URL 与控制器灵活映射 :通过 @RequestMapping@GetMapping 等注解将 HTTP 请求映射到 Java 方法
  • 约定大于配置:减少 XML 配置,通过注解驱动开发

下面是一个典型的 Spring MVC 控制器示例:

java 复制代码
package com.zmt.springioc.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequestMapping("/prop")     // 类级别映射:所有方法路径前缀为 /prop
@RestController              // @Controller + @ResponseBody,返回 JSON/文本
public class PropertiesController {

    @Value("${spring.datasource.url}")
    private String url;      // 从配置文件注入数据库连接地址

    @Value("${my.key1}")
    private Integer key1;    // Spring 自动进行类型转换 String → Integer

    @Value("${my.key2}")
    private Boolean key2;    // 自动类型转换 String → Boolean

    @RequestMapping("/read") // 方法级别映射:访问 /prop/read 时触发
    public String readProperties() {
        return "从配置文件中读取 url:" + url
             + "\n key1:" + key1
             + "\n key2:" + key2;
    }
}

关键点@RestController@Controller + @ResponseBody 的组合注解,表示该类中所有方法的返回值直接写入 HTTP 响应体,而不是跳转到视图页面。这是 RESTful API 开发中最常用的注解。

1.3 Spring Boot --- 快速开发整合包

Spring Boot 是 Spring 的封装整合工具,核心目标是简化项目搭建与配置。 它的定位是"脚手架"------帮你快速搭好项目骨架,让你专注于业务逻辑。

Spring Boot 的工作逻辑 :它本身不完成 Web 或数据库业务,而是帮你自动整合所需的模块。做 Web 开发就引入 spring-boot-starter-webmvc,做数据库操作就引入 MyBatis 或 JPA 的 Starter。

以项目中的 pom.xml 为例:

xml 复制代码
<!-- Spring Boot 项目只需引入 Starter,自动传递所需依赖 -->
<dependencies>
    <!-- Web MVC Starter:内含 Spring MVC、内嵌 Tomcat 等 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webmvc</artifactId>
    </dependency>

    <!-- Lombok:简化 Java Bean 代码 -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>

再看启动类,一个注解就能启动整个应用:

java 复制代码
package com.zmt.springioc;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication  // 核心注解:涵盖 @Configuration、@EnableAutoConfiguration、@ComponentScan
public class SpringIoCApplication {

    public static void main(String[] args) {
        // run() 返回的是 Spring IoC 容器上下文,可以从中获取任何被管理的 Bean
        ConfigurableApplicationContext context =
                SpringApplication.run(SpringIoCApplication.class, args);

        // 从容器中按名称获取 Bean
        UserController bean = (UserController) context.getBean("userController");
        bean.hello();
    }
}

@SpringBootApplication 深入理解 :这是一个组合注解,等价于同时标注了 @Configuration(声明配置类)、@EnableAutoConfiguration(启用自动配置)和 @ComponentScan(组件扫描)。一个注解完成三件事,这就是 Spring Boot 的"约定大于配置"哲学。

Spring Boot 的亮点

  • 内嵌 Web 服务器 (Tomcat/Jetty),无需部署 WAR 包,直接 java -jar 运行
  • Starter 依赖:一键引入技术栈,自动处理版本兼容
  • 自动配置:根据类路径中的依赖自动配置 Spring 应用

1.4 三者关系总结

用一句话概括三者的关系:

Spring MVC 和 Spring Boot 都隶属于 Spring 生态。Spring MVC 是 Spring 下的 MVC Web 子框架,Spring Boot 是基于 Spring 的快速开发整合包。Spring Boot 内置了 Spring MVC,做 Web 开发无需额外引入 MVC 依赖,开箱即用。


二、配置文件核心知识点

2.1 配置文件的作用 --- 解决硬编码

在了解配置文件之前,先看一个问题:硬编码

硬编码就是将可变数据直接写在源代码中。比如数据库连接地址:

java 复制代码
// 硬编码 --- 不推荐
String url = "jdbc:mysql://127.0.0.1:3306/testdb";
String username = "root";
String password = "root";

这样做的问题很明显:

  • 数据库地址变了,必须改代码、重新编译、重新部署
  • 不同环境(开发/测试/生产)需要维护多套代码
  • 密码写在代码里,安全性极差

配置文件的核心目的:将所有可变配置集中存放,程序启动时自动读取。这就像手机的"字体大小设置"------如果写死在代码里,所有人的字体都一样大;放入配置文件后,每个用户可以根据自己的偏好调整。

Spring Boot 项目启动时会自动加载 application.propertiesapplication.yml,开发者只需在代码中通过注解读取即可。

2.2 三类配置文件与优先级

Spring Boot 支持三种配置文件格式:

格式 说明
application.properties Spring Boot 默认配置文件,key=value 格式
application.yml YAML 格式,树形层级结构
application.yaml .yml 完全等价,就像 .html.htm 的关系

优先级规则 :当同一个配置项在 properties 和 yml 中同时存在时,properties 的优先级高于 yml,最终生效以 properties 中的值为准。这一机制常用于运维场景------用 properties 临时覆盖某些配置而不改动 yml 主文件。

2.3 properties 配置详解

2.3.1 基础语法

properties 采用纯 key=value 键值对格式,# 用于单行注释。以下为项目中的实际配置:

properties 复制代码
# ========== Spring-IoC 项目 application.properties ==========

# 应用名称
spring.application.name=Spring-IoC

# 服务器端口
server.port=9090

# MySQL 数据库连接配置
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/testdb
spring.datasource.username=root
spring.datasource.password=root

# 自定义配置项
my.key1=5
my.key2=true
2.3.2 使用 @Value 读取配置

在代码中通过 @Value("${配置key}") 注解将配置值注入到 Java 类属性中。Spring 会自动进行类型转换 ------字符串 "5" 转为 Integer"true" 转为 Boolean

java 复制代码
package com.zmt.springioc.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequestMapping("/prop")
@RestController
public class PropertiesController {

    @Value("${spring.datasource.url}")
    private String url;          // 注入数据库连接地址

    @Value("${my.key1}")
    private Integer key1;        // "5" → Integer 类型自动转换

    @Value("${my.key2}")
    private Boolean key2;        // "true" → Boolean 类型自动转换

    @RequestMapping("/read")
    public String readProperties() {
        return "从配置文件中读取 url:" + url
             + "\n key1:" + key1
             + "\n key2:" + key2;
    }
}

启动项目后访问 http://localhost:9090/prop/read,即可看到从配置文件注入的值。 Spring 在启动时会扫描 @Value 注解,从配置文件中读取对应的值并注入。

2.3.3 properties 的核心缺点

仔细看上面的数据库配置,spring.datasource 这个前缀重复了 3 次。在实际项目中,可能有几十条相关配置,大量重复前缀会让文件变得臃肿、可读性下降:

properties 复制代码
# 冗余示例 --- 相同前缀反复出现
spring.datasource.url=...
spring.datasource.username=...
spring.datasource.password=...
spring.datasource.driver-class-name=...
spring.datasource.hikari.maximum-pool-size=...
# ... 更多重复前缀 ...

YAML 正是为解决这个冗余问题而生。

2.4 yml(YAML)配置详解

2.4.1 基础语法

YAML 全称 Yet Another Markup Language (另一种标记语言),采用树形层级结构 ,通过缩进表达父子关系。基本格式为 key: value

⚠️ 强制规则:冒号后面必须跟一个英文空格key:value(无空格)会被判定为语法错误,导致项目启动失败。这也是 YAML 配置中最常见的踩坑点。

以下为项目中的 yml 配置:

yaml 复制代码
# ========== Spring-IoC 项目 application.yml ==========

# 自定义 key
yaml: aa

# 数据库配置 --- 层级结构,无需重复前缀
spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/testdb
    username: root
    password: root

# 字符串转义测试
string:
  str1: Hello \n Spring Boot.        # 默认字符串,\n 作为普通文本
  str2: 'Hello \n Spring Boot.'      # 单引号:\n 不转义,原样输出
  str3: "Hello \n Spring Boot."      # 双引号:\n 会被解析为换行符

# 对象配置
student:
  id: 1
  name: Java
  age: 18

# 集合与 Map 配置
dbtypes:
  name:                  # List 集合
    - mysql
    - sqlserver
    - db2
  map:                   # Map 键值对
    k1: kk1
    k2: kk2
    k3: kk3

与 properties 对比,同样的数据库配置在 yml 中只需要写一次 spring.datasource,子配置通过缩进排列,一目了然。

2.4.2 字符串单/双引号规则(易错点)

这是 YAML 配置中极易混淆的细节。项目中专门设置了三个测试值来验证:

yaml 复制代码
string:
  str1: Hello \n Spring Boot.       # 无引号 --- 与单引号行为一致
  str2: 'Hello \n Spring Boot.'     # 单引号 --- 转义字符原样输出
  str3: "Hello \n Spring Boot."     # 双引号 --- 转义字符正常转义

通过 YamlController 读取并打印:

java 复制代码
@RequestMapping("/yaml")
@RestController
public class YamlController {

    @Value("${string.str1}")
    private String str1;   // 输出:Hello \n Spring Boot. (\n 未转义)

    @Value("${string.str2}")
    private String str2;   // 输出:Hello \n Spring Boot. (单引号,\n 原样)

    @Value("${string.str3}")
    private String str3;   // 输出:Hello (换行)Spring Boot. (双引号,\n 转义为换行)

    @RequestMapping("/read")
    public String read() {
        System.out.println(str1);
        System.out.println(str2);
        System.out.println(str3);
        return "success";
    }
}

规则总结

写法 效果
字符串'字符串' 转义字符(\n\t 等)不生效,作为普通文本输出
"字符串" 转义字符正常生效\n → 换行,\t → 制表符

实践建议 :大多数场景下无需加引号。当你确实需要在配置值中使用 \n 换行等转义字符时,使用双引号包裹。

2.4.3 使用 @ConfigurationProperties 批量绑定

除了 @Value 逐条读取,Spring Boot 还提供了 @ConfigurationProperties 注解,支持按前缀批量绑定配置到 Java 对象,非常适合层级化的 yml 配置。

示例一:绑定对象

java 复制代码
package com.zmt.springioc.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

@Data
@Configuration                        // 声明为 Spring 配置类
@ConfigurationProperties(prefix = "student")  // 绑定 yml 中 student 前缀下的所有配置
public class Student {
    private Integer id;               // student.id → 1
    private String name;              // student.name → "Java"
    private Integer age;              // student.age → 18
}

示例二:绑定 List 和 Map

java 复制代码
package com.zmt.springioc.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import java.util.List;
import java.util.Map;

@Data
@Configuration
@ConfigurationProperties(prefix = "dbtypes")
public class DbTypeConfig {
    private List<String> name;        // 绑定 name 列表:[mysql, sqlserver, db2]
    private Map<String, String> map;  // 绑定 map 键值对:{k1=kk1, k2=kk2, k3=kk3}
}

示例三:嵌套对象绑定(来自 captch-demo 项目)

java 复制代码
// CaptchaProperties.java --- 主配置类
package com.zmt.captchdemo.model;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

@Data
@Configuration
@ConfigurationProperties(prefix = "captcha")
public class CaptchaProperties {
    private Integer width;       // captcha.width → 150
    private Integer height;      // captcha.height → 60
    private Session session;     // captcha.session → 嵌套对象自动绑定
}

// Session.java --- 嵌套对象
package com.zmt.captchdemo.model;

import lombok.Data;

@Data
public class Session {
    private String code;         // captcha.session.code → "code"
    private String date;         // captcha.session.date → "date"
}

对应的 yml 配置:

yaml 复制代码
captcha:
  width: 150
  height: 60
  session:
    code: code
    date: date

@Value vs @ConfigurationProperties 对比

维度 @Value @ConfigurationProperties
读取方式 逐条指定完整 key 按前缀批量绑定
适用场景 少量配置、简单值 层级配置、批量绑定
类型安全 需手动转换 自动类型映射
松散绑定 不支持 支持(my-keymyKey

建议 :当某个前缀下有 ≥ 3 条配置时,优先使用 @ConfigurationProperties,代码更简洁、更易维护。

2.4.4 yml 优缺点总结

优点

  1. 层级清晰、可读性高,彻底解决 properties 的冗余前缀问题
  2. 原生支持对象、List、Map 等多种数据类型,无需额外解析
  3. 跨语言通用,Java、Python、Go、JavaScript 等主流语言均可使用

缺点

  1. 不适合超大型、极其复杂的配置场景(此时可考虑外部配置中心如 Nacos、Apollo)
  2. 对缩进和空格格式要求极高------一个缩进错误直接导致项目启动失败,排查起来比 properties 更费时

三、整体总结

3.1 开发选型建议

日常 Spring Boot 项目优先推荐使用 yml 配置文件。它的层级结构清晰、无冗余前缀,写起来简洁、读起来直观。仅以下两种情况可继续使用 properties:

  • 遗留老项目:改造 yml 成本大于收益
  • 极简小项目:只有三五条配置,yml 层级的优势体现不出来

3.2 依赖关系速记

Spring Boot 内置了 Spring MVC,引入 spring-boot-starter-webmvc 后即可直接编写 Controller,无需额外配置。Spring Boot 是"壳",Spring MVC 是"Web 引擎",Spring 是"底层核心"------三者是层层包含的关系。

3.3 配置读取方式

两种配置文件都支持 @Value("${key}") 逐条读取。Spring Boot 额外提供 @ConfigurationProperties(prefix = "xxx") 支持按前缀批量绑定,配合 yml 的层级结构使用效果最佳。


全文总结

本文从 Spring 生态的三大核心概念出发,逐步深入到配置文件的使用细节,核心内容回顾:

  1. Spring 的核心是 IoC 容器------将对象创建和依赖管理从代码中剥离,实现高内聚低耦合
  2. Spring MVC 是 Web 层子框架,依托 Spring 内核,通过注解驱动简化 Web 开发
  3. Spring Boot 是快速开发整合包,通过自动配置和 Starter 依赖大幅降低项目搭建成本
  4. 配置文件是解决硬编码的关键手段,properties 和 yml 各有适用场景
  5. yml 凭借层级结构和丰富的数据类型支持,成为现代 Spring Boot 项目的首选配置格式

核心知识点复盘

知识点 关键内容
IoC / DI 控制反转:对象创建由容器管理;依赖注入:依赖从外部注入而非内部 new
@SpringBootApplication 组合注解 = @Configuration + @EnableAutoConfiguration + @ComponentScan
@RestController = @Controller + @ResponseBody,RESTful 接口开发标配
@Value("${key}") 逐条读取配置,支持自动类型转换
@ConfigurationProperties 按前缀批量绑定,适合层级化配置
yml 空格规则 key: value 冒号后必须有空格,否则语法错误
yml 引号规则 单引号/无引号不转义特殊字符,双引号转义特殊字符
配置文件优先级 properties > yml > yaml(同名配置下)

常见问题 / 避坑指南

1. yml 缩进报错导致项目启动失败?

确保缩进统一使用空格(不要混用 Tab),冒号后必须有空格。IDE 会给出语法高亮提示,启动前先检查 yml 文件是否有红色波浪线。

2. @Value 注入的值为 null?

检查 key 是否写错,确认配置文件是否在 src/main/resources 目录下。另外,@Value 不能注入到 static 字段中------静态字段在类加载时就确定了,而 Spring 的依赖注入发生在对象实例化阶段。

3. @ConfigurationProperties 不生效?

确保类上同时标注了 @Configuration(或 @Component)和 @ConfigurationProperties。如果 IDE 提示 "Spring Boot Configuration Annotation Processor not configured",可以在 pom.xml 中添加 spring-boot-configuration-processor 依赖以启用自动补全。

4. properties 和 yml 同时存在,哪个生效?

properties 优先级更高。如果你在 yml 中配置了 server.port=8080,但在 properties 中配置了 server.port=9090,最终生效的端口是 9090。这个特性可用于临时覆盖配置,但日常开发建议只保留一种格式,避免混淆。

5. yml 中如何写多行字符串?

使用 |(保留换行)或 >(折叠换行为空格)符号:

yaml 复制代码
description: |
  这是第一行
  这是第二行

6. 配置文件中的敏感信息如何处理?

数据库密码等敏感信息不应明文写在配置文件中。生产环境建议使用环境变量、JVM 参数(-Dspring.datasource.password=xxx)或专业的配置中心(如 Nacos、Spring Cloud Config)来管理敏感配置。


本文基于 Spring Boot 4.1.0 实战项目编写,所有代码均可直接运行验证。希望这篇文章能帮助你建立对 Spring 生态和配置文件的系统性认知。

相关推荐
攻城有术1 小时前
专项攻克-springcloud及其组件
后端·spring·spring cloud
IanSkunk1 小时前
企业AI Agent生产化落地:从技术架构到实施服务的全链路分析
java·人工智能·架构
岁岁养乐多2 小时前
Java 序列化相关问题
java·开发语言
小短腿乄2 小时前
java实现pdf加水印+签名
java·开发语言·pdf
Kripath_Rion3 小时前
带你速通计算机经典论文(一):分布式系统篇
分布式·后端·架构
云烟成雨TD3 小时前
Micrometer 系列【29】源码分析:MeterRegistry 实例化流程
java·云原生·micrometer
聆风吟º3 小时前
【金仓数据库征文】Java 应用接入金仓数据库:从驱动、连接池到存储过程调试的踩坑实录
java·开发语言·数据库
砍材农夫4 小时前
物联网实战|Spring Boot MQTT平台 |emqx broker实战
spring boot·spring·spring cloud·mybatis
似璟如你4 小时前
Java 开发者的 Go 语法基础:从 0 开始快速上手 Go
java·开发语言·后端·golang·go·编程语言