SpringBoot-快速入门
SpringBoot-快速入门

SpringBoot的环境要求
spring官网中的SpringBoot的参考文档中有写环境的要求,这里以SpringBoot-3.5.12版本为例说一下环境要求

| 环境&工具 | 版本(or later) |
|---|---|
| Java | 17+ |
| Spring Framework | 6.2.17+ |
| Maven | 3.6.3 or later |
| Gradle | Gradle 7.x(7.6.4 or later) or 8.x(8.4 or later) |
SpringBoot是什么
SpringBoot是基于Spring生态的一个快速开发脚手架,用来简化Spring应用的搭建和开发,让你能写很少配置、直接运行一个生成级Java应用
SpringBoot的定义
官方定义:
Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can "just run".We take an opinionated view of the Spring platform and third-party libraries so you can get started with minimum fuss. Most Spring Boot applications need minimal Spring configuration.
翻译为:
Spring Boot可以轻松创建独立的、基于Spring的生成级应用程序,让你"只需要运行"。我们对Spring平台和第三方库有自己的看法,这样你就可以轻松上手。大多数SpringBoot应用程序只需要很少的Spring配置。
- 基于Spring生态:底层还是Spring Framework,只是在你和Spring之间加了一层"约定大于配置"的简化层
- 独立可运行:打包成可执行jar,内嵌Tomcat/Jetty等Web服务器,不需要再部署到外部容器
- 生产级:自带监控、健康检查、外部化配置等"生产就绪"特性
- 开箱即用:通过场景启动器(starter)和自动配置,大幅减少样板配置和XML
可以将SpringBoot理解为:
SpringBoot = Spring + 约定 + 自动配置 + 内嵌容器 + 生产级特性
SpringBoot解决了什么问题
解决了传统Spring开发的典型痛点:
- 配置繁琐:大量XML或Java配置,手动配置数据源、事务、MVC、安全等
- 依赖管理麻烦:容易冲突,版本需要自己协调
- 部署麻烦:需要打包成WAR,部署到Tomcat容器上
SpringBoot的目的就是尽量零配置,快速搭建一个可以直接运行,接近生产标准的应用
SpringBoot的特性
官方列出的特性如下:
-
Create stand-alone Spring applications:创建独立的Spring应用程序
-
Embed Tomcat,Jetty or Undertow directly(no need to deploy WAR files):直接嵌入Tomcat、Jetty、Undertow等Web服务器+Servlet容器(无需部署war包)
-
Provide opinionated 'starter' dependencies to simplify your build configuration:提供可选的starter(场景启动器)来简化应用配置
-
Automatically configure Spring and 3rd party libraries whenever possible:按需自动配置Spring以及第三方依赖
-
Provide production-ready features such as metrics,health checks,and externalized configuration:提供生产级特性如监控指标、健康检查、外部化配置等
-
Absolutely no code generation and no requirement for XML configuration:绝对无代码生成,不需要XML配置
注:
springboot为每一个场景提供了一个依赖即场景启动器(starter),比如web场景的依赖:spring-boot-starter-web
如果引入了对应的依赖即对应的场景,那么这个场景的所有配置都会自动配置好。对应场景会有默认的配置(约定大于配置),也可以通过配置文件来修改默认配置(自定义)
快速构建SpringBoot项目
构建SpringBoot项目示例
1.指定父POM
所有springboot项目都必须继承自 spring-boot-starter-parent
<!-- 所有springboot项目都必须继承自 spring-boot-starter-parent -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.9</version>
</parent>
2.子模块导入web场景和SpringBoot打包插件
<dependencies>
<!-- web开发的场景启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<!-- SpringBoot应用打包插件 -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
3.主启动类
/**
* 启动springboot项目的主入口程序
*/
@SpringBootApplication
public class MainApplication {
public static void main(String[] args) {
SpringApplication.run(MainApplication.class, args);
}
}
4.控制层接口
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello() {
return "Hello spring boot";
}
}
5.打包为jar包并运行
通过mvn命令构建jar包,并通过java -jar命令运行程序
6.测试接口
启动程序后访问网页:http://localhost:8080/hello

如果能够正常返回字符串如上图所示则表示快速构建的SprinBoot项目功能正常
示例中体现的特性
- 简化整合
导入相关的场景(场景启动器-starter),拥有相关的功能。
SpringBoot支持的场景可参见官方文档:
https://docs.spring.io/spring-boot/3.5/reference/using/build-systems.html#using.build-systems.starters
官方提供的场景命名方式: spring-boot-starter-*
第三方提供的场景命名方式: *-spring-boot-starter
- 简化开发
无需编写任何配置,直接开发业务
- 简化配置
application.properties配置文件:
集中式管理配置,只需要修改这一个文件即可
配置基本都有默认值
能编写的所有配置可参见官方文档:
https://docs.spring.io/spring-boot/3.5/appendix/application-properties/index.html
- 简化部署
打包为可执行的jar包
- 简化运维
修改配置不需要重新打包,修改外部的application.properties文件即可
使用Spring Initializr 一键构建SpringBoot项目
Spring Initializr是Spring官方提供的一个基于Web的项目生成工具
核心配置项
- Project Metadata(项目元数据)
- Group:项目组名
- Artifact:项目名称
- Name:项目显示名称
- Packaging:打包方式:Jar(微服务/独立运行),War(传统部署到外部Tomcat)
- Java Version:JDK版本
- Dependencies(依赖选择):在勾选SpringBoot版本后会根据版本自动匹配最兼容的依赖版本
常见的三种构建方式
方式一:通过官网页面构建项目
官方Spring Initializr页面:https://start.spring.io/

在配置好参数和依赖后点击下方的GENERATE按钮后,会从浏览器中下载一个.zip的压缩包
方式二:通过IDEA集成构建项目
IDEA内置了对Spring Initializr的支持


在IDEA中点击新建项目,选择Spring Initializr后填写项目元数据与依赖后点击Creat后完成构建
方式三:通过命令行
Spring Initializr本质上暴露了RESTful API,可以通过命令行直接生成
# 使用 curl 调用 API 生成项目
curl https://start.spring.io/starter.zip -d type=maven-project -d language=java -d bootVersion=3.1.0 -d baseDir=demo -d groupId=com.example -d artifactId=demo -d name=demo -d dependencies=web,mybatis,mysql -o demo.zip
SpringBoot的常用注解
SpringBoot是注解驱动优先,并且默认情况下不强制你写任何XML配置文件
组件(Bean)注册注解
声明配置类的注解(@Configuration和@SpringBootConfiguration)
@SpringBootConfiguration注解上面直接标注了@Configuration。
在Spring容器看来,一个类上标了@SpringBootConfiguration等同于标了@Configuration。
@SpringBootConfiguration和@Configuration的作用完全一样:告诉Spring,这是一个配置类,里面可能有@Bean注解,请把这个类作为配置元数据来解析。
这两个配置类的区别主要是语义不同,为的是划清"阵营"的界限:
@Configuration是Spring Framework(核心框架)的注解,从Spring3.0就已存在,属于底层基础。
@SpringBootConfiguration是SpringBoot的注解,专门为SpringBoot服务。
日常使用中手写配置类只用@Configuration,@SpringBootConfiguration留给框架和底层去使用
管理对象创建和生命周期的注解(@Bean和@Scope)
@Bean
在全注解时代,@Bean的作用就是完美替代XML中
标签
作用位置:写在配置类里面的方法上
作用:告诉Spring: 请调用这个方法,把方法返回的对象拿走,注册到Spring容器中,以后有人要这个对象,直接从容器中拿,不用自己new了
@Scope
@Bean注解默认时单例的(全局唯一),但如果每次想要一个全新的对象就需要@Scope
作用位置:写在方法上(配合@Bean使用),也可以写在类上(配合@Component使用)
作用:指定该Bean的作用域(生命周期范围)
常见的作用域:
singleton:默认值,整个Sping容器中只有一个实例。适用于工具类、Service、DAO、配置类等绝大多数情况。
prototype:原型,每次向Spring要这个对象,Spring都会给你new一个全新的。适用于有状态的对象(比如每次请求需要不同的连接、任务对象)。
request:请求,在一次HTTP请求中有效,不同请求拿到不同的实例。仅在Web环境中有效。
session:会话。再一次HTTP Session中有效。仅在Web环境中有效。
application:应用。在一个ServletContext生命周期内有效。仅在Web环境中有效。
将对象自动注册到Spring容器的注解(@Component,@Controller,@Service,@Repository)
@Component、@Controller、@Service、@Repository这四个注解的效果是相同的,都是把这个类示例化成一个单例Bean。它们在底层本质上完全一样,唯一的区别是为了语义化分层。
@Controller(控制层/表现层)
@Controller(控制层/表现层)
角色:系统的"门面"。负责接收前端发来的HTTP请求,提取参数,调用Service处理业务,最后把结果返回给前端。
位置:通常放在类上,类名以xxController结尾。
注:在SpringBoot开发中,一般用该注解的升级版本@RestController,专门用于直接返回JSON数据。
@Controller + @ResponseBody = @RestController
@Service(业务逻辑层)
角色:系统的"大脑"。负责处理具体的业务逻辑。
位置:通常放在类上,类名以xxService或xxServiceImpl结尾。
@Repository(持久层/数据访问层)
角色:系统的"手脚"。专门负责和数据库打交道。
位置:通常放在类上,类名以xxDao,xxMapper,xxRepository结尾。
注:Spring为@Repository配置了一个特殊的后置处理器:它能自动捕获底层数据库抛出的特定异常,并将它们统一转换为spring体现下的DataAccessException异常。这意味着业务层不需要catch具体的数据库异常,只需要catch Spring的通用异常即可,实现了业务代码与底层数据库技术的解耦。
@Component(通用组件)
角色:"杂牌军"收容所。当一个类不属于上述角色中的任意一种且需要被Spring管理,就用@Component。
常见场景:工具类、自定义拦截器、过滤器、跨切面的通用处理类。
包扫描和显示导入的注解(@ComponentScan和@Import)
如果说Spring容器是一个"大仓库",那么@ComponentScan和@Import就是往仓库里面"进货"的两种截然不同的方式,@ComponentScan和@Import都是把类变成Spring容器里面的Bean,但是两者的工作机制完全相反
@ComponentScan: 自动发现与扫描
工作机制:它依赖与Spring的类路径扫描器。它会在底层遍历你指定的目录下的所有.class文件,然后检查这些类的字节码上有没有@Component(以及它派生注解@Controller、@Service、@Repository)。有就实例化,没有就跳过。
特点:
被动发现:不需要知道具体有多少个类,只要它们符合"贴了标签"的规则,就会被自动找出来。
受限于包路径:它只能扫描你指定的basePackages及其子包。超出这个范围(比如其他Jar包的类),就无法生效。
注:在SpringBoot中很少手动写@ComponentScan,因为@SpringBootApplication这个复合注解默认内置了@ComponentScan,并且默认扫描范围是该启动类所在的包及其子包。
@Import: 显示导入与注册
工作机制:它不扫描文件系统,就是单纯地把你注解中写死的哪些Class对象,直接塞到Spring注册表。哪怕这个类上没有任何注解,只有写在@Import中,它就能变成Bean。
特点:
主动精准:指定类,需要谁进谁就进。
无视包路径限制:可以跨Jar包导入。
无视注解限制:可以导入没有@Component的普通类,甚至可以通过ImportSelector动态导入。
@ComponentScan和@Import的使用场景
@ComponentScan用来管理自身的业务代码,@Import用来导入第三方库和框架底层。一内一外构建Spring容器的强大的对象管理能力
组件注册注解使用示例
引入依赖
<!-- 所有springboot项目都必须继承自 spring-boot-starter-parent -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.9</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.27</version>
<scope>compile</scope>
</dependency>
</dependencies>
<!-- SpringBoot应用打包插件 -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
POJO类
public class User {
private Long id;
private String name;
public String getName() {
return name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
}
配置类
//替代之前的配置类 -普通配置类用@Configuration,springboot配置类用@SpringBootConfiguration
//@Configuration
//给容器中放入指定类型的组件,组件名称默认为全类名
@Import(FastsqlException.class)
@SpringBootConfiguration
public class AppConfig {
@Bean("userAlex")
/**
* 替代配置类之前的properties标签
* 组件在容器中名称默认为方法名,也可以在@Bean注解进行修改
*/
@Scope("prototype")
/**
* 替代配置类之前的scope标签
* 默认为单实例singleton,多实例为prototype
*/
public User getUserOne() {
User user = new User();
user.setId(1L);
user.setName("alex");
return user;
}
// @Bean
// public FastsqlException fastsqlException() {
// return new FastsqlException();
// }
}
主启动类
/**
* 启动springboot项目的主入口程序
*
* 主程序包 com.shen.annotations
* 可以使用@ComponentScan或@SpringBootApplication中的scanBasePackages属性来指定扫描路径
*/
//@ComponentScan("com.shen.annotations")
@SpringBootApplication(scanBasePackages = "com.shen.annotations")
@SpringBootApplication
public class CommonAnnoationsApplication {
public static void main(String[] args) {
//获取spring容器
var ioc = SpringApplication.run(CommonAnnoationsApplication.class, args);
String[] names = ioc.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
System.out.println("========================================");
String[] types = ioc.getBeanNamesForType(User.class);
for (String type : types) {
System.out.println(type);
}
Object userOne = ioc.getBean("userAlex");
Object userTwo = ioc.getBean("userAlex");
System.out.println(userOne == userTwo);
System.out.println("========================================");
String[] type1 = ioc.getBeanNamesForType(FastsqlException.class);
for (String type : type1) {
System.out.println(type);
}
}
}
条件注解(@ConditionalOnXxx)
SpringBoot的核心设计理念之一就是"约定大于配置",而实现这一理念背后的关键技术就是条件注解
条件注解运行开发者根据特定的条件来决定是否注册Bean或执行某些配置。这极大地实现了SpringBoot的自动装配功能,即只有在满足特定条件时,组件才会被加载。由于@ConditionOnXxx系列注解较多这里只说明类条件注解和Bean条件注解,其他条件注解可以参见官网:
类条件注解
这类注解用于判断特定的类是否存在于classpath(类路径)中
@ConditionalOnClass
- 含义:当给定的类名在类路径中存在时,匹配成功
- 场景:当你需要依赖某个第三方库时,例如:只有在项目中引入了Jackson库,才配置JSON序列化器
ConditionalOnMissingClass
- 含义:当给定的类名在类路径中不存在时,匹配成功
- 场景:通常用于提供默认实现。如果用户没有引入某个类,则使用默认的简单实现
Bean条件注解
这里注解用于判断容器中是否存在特定的Bean
@ConditionalOnBean
- 含义:当Spring容器中存在指定的Bean时,匹配成功
- 场景:依赖注入,例如:只有当存在DataSource Bean时,才创建JdbcTemplate
@ConditionalOnMissingBean
- 含义:当Spring容器不存在指定的Bean时,匹配成功
- 场景:这是自动配置中最常用的注解。它允许开发者覆盖默认配置。如果开发者自己定义了一个Bean,SpringBoot的默认Bean就不会生效
条件注解示例
POJO类
public class Cat {
private Long id;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Dog {
private Long id;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
条件配置类
/**
* 条件注解演示场景-@ConditionalOnXX
* 如果存在
* FastsqlException
* 这个类,给容器中放⼀个Cat组件,名为 catOne,
* 否则,就给容器中放⼀个Dog组件,名为dogOne
* 如果系统中有dogOne这个组件,就给容器中放⼀个 User组件,名userDog
* 否则,就放⼀个User组件,名叫userNoDog
*/
@Configuration
public class ConditionalConfig {
@Bean(name = "catOne")
@ConditionalOnClass(name = "com.alibaba.druid.FastsqlException")
public Cat getCat() {
return new Cat();
}
@Bean(name = "dogOne")
@ConditionalOnMissingClass(value = "com.alibaba.druid.FastsqlException")
public Dog getDog() {
return new Dog();
}
@Bean(name = "userDog")
@ConditionalOnBean(name = "dogOne")
public User getUserDog() {
return new User();
}
@Bean(name = "userNoDog")
@ConditionalOnMissingBean(name = "dogOne")
public User getUserNoDog(){
return new User();
}
}
启动类
@SpringBootApplication
public class CommonAnnoationsApplication {
public static void main(String[] args) {
var ioc = SpringApplication.run(CommonAnnoationsApplication.class, args);
String[] names = ioc.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
} System.out.println("=================conditional=======================");
String[] dogType = ioc.getBeanNamesForType(Dog.class);
for (String type : dogType) {
System.out.println(type);
}
String[] catType = ioc.getBeanNamesForType(Cat.class);
for (String type : catType) {
System.out.println(type);
}
}
}
属性绑定注解
在SpringBoot中,@ConfigurationProperties和@EnableConfigurationProperties是实现类型安全配置的核心搭档。它们解决了使用@Value注解在配置项过多时代码臃肿、无法复用、不支持复杂对象校验等问题
- @ConfigurationProperties:负责搬运,将配置文件中键值对映射到Java Bean的属性上
- @EnableConfigurationProperties:负责注册,告诉Spring容器去识别并管理这个搬运工Bean
@ConfigurationProperties(配置绑定)
这个注解通常标注在POJO(Plain Old Java Object)类上,用于将外部配置(如application.yml或application.properties)绑定到类的字段上
注解特性:
- 前缀匹配:通过prefix或value指定配置的前缀
- 松散绑定:支持多种命名风格。例如配置文件中的user.first-name、user.firstName、user.first_name都可以映射到Java类中的firstName字段
- 类型转换:自动将字符串转换为对应的数据类型(如:Integer、Long、Date等)
- JSR-303校验:支持@Validated注解,配合@NotNull,@Email等进行配置校验
@EnableConfigurationProperties(启用注册)
此注解用于激活标注了@ConfigurationProperties的类,使其成为一个Spring容器管理的Bean
通常,为了让Spring识别一个类,我们会加上@Component。但在自动配置场景下,或为了保持POJO的纯粹性(不污染业务代码),我们不想在POJO上加@Component。此时就需要在一个配置类中使用@EnableConfigurationProperties来显式注册
属性绑定注解示例
POJO类
/**
* 属性绑定注解-@ConfigurationProperties,既可以在对应类中绑定也可以在配置类中绑定
*/
//@Component
//@ConfigurationProperties(prefix = "pig")
public class Pig {
private Long id;
private String name;
private String age;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
@Override
public String toString() {
return "Pig{" +
"id=" + id +
", name='" + name + '\'' +
", age='" + age + '\'' +
'}';
}
}
@ConfigurationProperties(prefix = "sheep")
public class Sheep {
private Long id;
private String name;
@Override
public String toString() {
return "Sheep{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
配置类
//@EnableConfigurationProperties:开启sheep组件的属性绑定并默认把这个组件放到容器中,主要用于导入第三方写好的组件进行属性绑定
//springboot默认只扫描自己主程序所在的包。如果导入了第三方包,即使组件上标注了@Componment、@ConfigurationProperties注解也没用,因为组件都扫描不进来
@EnableConfigurationProperties(Sheep.class)
@SpringBootConfiguration
public class AppConfig {
/**
* 属性绑定注解-@ConfigurationProperties,既可以在对应类中绑定也可以在配置类中绑定
*/
@Bean
@ConfigurationProperties(prefix = "pig")
public Pig getPig() {
return new Pig();
}
}
配置文件
server:
port: 8080
pig:
id: 1
name: 佩奇
age: 5
sheep:
id: 1
name: 苏西
启动类
@SpringBootApplication
public class CommonAnnoationsApplication {
public static void main(String[] args) {
var ioc = SpringApplication.run(CommonAnnoationsApplication.class, args);
String[] names = ioc.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
System.out.println("=================config bind=======================");
Pig pig = ioc.getBean(Pig.class);
System.out.println(pig);
Sheep sheep = ioc.getBean(Sheep.class);
System.out.println(sheep);
}
}
YAML配置文件
YAML是一种人类可读的数据序列化语言。它全程是"YAML Ain't Markup Language",这强调它关注数据本身,而非文档标记(如HTML)
YAML设计理念
YAML的设计目标是让人们容易阅读和编写。它结合了XML的数据描述能力、Python的简洁语法以及C语言的转义习惯,非常适合来做配置文件、数据交换格式或日志文件。
在SpringBoot中,YAML已经称为了比传统properties文件更受欢迎的配置方式。它利用YAML的层级结果,完美契合了SpringBoot复杂的配置需求。
YAML语法特点
- 大小写敏感
- 使用缩进表示层级关系-- k: v,使用空格分割k,v
- 缩进时不允许使用Tab键,只允许使用空格(一般推荐2个空格),缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
- "#"表示注释,从这个字符一直到行尾,都会被解析器忽略
- 数据类型丰富:原生支持标量(字符串、整数、浮点数)、列表、映射
- 对象:键值对的集合,如:映射(map)、哈希(hash)、字典(dictionary)
- 数组:一组按次序排列的值,如序列(sequence)、列表(list)
- 纯量:单个的、不可再分的值,如字符串、数组、bool、日期
YAML使用示例
pom依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--lombok简化JavaBean开发,自动生成构造器、getter/seter、自动生成Builder模式等-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>compile</scope>
</dependency>
</dependencies>
<!-- SpringBoot应用打包插件 -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
POJO类
@Data
public class Cat {
private String name;
private Integer age;
}
@Data
public class Child {
private String name;
private Integer age;
private Date birthday;
/**
* 字符串数组
*/
private List<String> text;
}
@Data
public class Dog {
private String name;
private Integer age;
}
@Component
@Data
@ConfigurationProperties(prefix = "person")
public class Person {
private String name;
private Integer age;
private Date birthday;
private Boolean like;
/**
* 嵌套对象
*/
private Child child;
/**
* 对象数组
*/
private List<Dog> dogs;
/**
* kv键值对
*/
private Map<String, Cat> cats;
}
YAML配置文件
# 1. k: v # k v之前是空格区分 k:
# 2. 属性是有层级关系,使用下一行,空两个空格
# 3. 左侧对齐的代表同一层级的属性
# 4.大小写敏感
# birthDay推荐写为birth-day
# 单引号不会转义 ,双引号会转义 eg: \n
# 大文本,|开头,大文本并列写在下层,保留文本格式。>开头,大文本写在下层,压缩换行符换为空格
# 多文档合并,使用===可以把多个yaml文档合并在一个文件中,每个文档依然认为内容独立
server:
port: 18089
spring:
servlet:
multipart:
max-file-size: 1MB
---
person:
name: 小明
age: 24
birthday: 2008/12/12 20:00:00
like: true
child:
name: 小小明
age: 5
birth-day: 2020/8/8
# text: ["a","b"]
text:
- |
abcd
defg
- >
1234
5678
- '123\n123'
- "ab\nab"
dogs:
- name: 小白
age: 1
- name: 小黑
age: 3
cats:
c1:
name: 妙妙
age: 5
c2: {name: 叔, age: 3}
启动类
@SpringBootApplication
public class YamlApplication {
public static void main(String[] args) {
// java10: 局部变量类型自动推断
var ioc = SpringApplication.run(YamlApplication.class, args);
Person person = ioc.getBean(Person.class);
System.out.println(person);
}
}
日志配置
SpringBoot的日志体系非常强大且灵活,它内部默认使用了SLF4J(日志门面)+Logback(日志实现)的组合。在大多数情况下,开发者不需要引入额外的日志依赖即可直接使用
日志在日常中的使用
在代码中打印日志通常由两种方式
- 传统方式(手动创建Logger)
- 使用Lombok(推荐):引用Lombok,直接使用@Slf4j注解即可
SpringBoot是如何把日志默认配置好的
- 每个starter场景,都会导入一个核心场景
spring-boot-starter - 核心场景引入了日志的所用功能
spring-boot-starter-logging - 默认使用了Logback+SLF4J组合作为底层日志
- 日志是系统已启动就要用,xxAutoConfiguration是系统启动之后放好的组件,是后来用的。
- 日志是利用监听器机制配置好的,
ApplicationListener - 日志所有的配置都可以通过修改配置文件实现,以
logging开始的所有配置
日志使用示例
pom依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--lombok简化JavaBean开发,自动生成构造器、getter/seter、自动生成Builder模式等-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>compile</scope>
</dependency>
</dependencies>
<!-- SpringBoot应用打包插件 -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
YAML配置文件
logging:
pattern:
# 控制台日志打印配置
# console: '%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] %logger{15} ===> %msg%n'
# 单独配置日期打印格式
dateformat: yyyy-MM-dd HH:mm:ss
level:
# 默认所有日志没有精确指定级别就使用root的默认级别
root: info
# 精确调整某个包下的日志级别
com.shen.log.controller: info
# 调整分组的日志级别
abc: error
# spring内置了两个分组,web请求方面,sql查询方面
sql: trace
web: trace
# 日志分组,便于统一修改分组中的日志级别
group:
abc: com.shen.log.aaa,com.shen,com.aaa,com.bb
# 指定日志的文件路径,日志文件默认叫spring.log
file:
# 指定日志文件的名可以只写名字也可以写路径+名字,因此name和path同时存在时只看name
name: hello.log
path: F:\\
# 日志归档与切割 ,springboot默认整合logback,如果使用log4j2则需要添加log4j2.xml或log4j2-spring.xml
logback:
rollingpolicy:
# 日志归档名称
file-name-pattern: ${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz
# 日志单文件最大空间
max-file-size: 10MB
# 日志文件被删除之前,可以容纳的最大大小,如果超过指定空间则会删除旧日志文件
total-size-cap: 1GB
# 日志文件保存的最大天数
max-history: 7
控制层接口
@Slf4j
@RestController
public class HelloController {
@GetMapping("/h")
public String hello() {
// Logger log = LoggerFactory.getLogger(HelloController.class);
// log.info("/h请求进来了");
log.info("/h请求进来了");
return "hello";
}
@GetMapping("/test")
public String testLog(String msg) {
log.trace("trace日志---");
log.debug("debug日志---");
//springboot默认打印info级别及其以上级别日志
log.info("info日志---msg: [{}]", msg);
log.warn("warn日志---");
log.error("error日志---");
return "test";
}
}
SpringBoot-依赖管理机制
SpringBoot的依赖管理机制使其核心特性之一,它极大地简化了构建配置,让开发者无需为依赖版本操心。其核心机制主要由"BOM(Bill of Materials-物料清单)"和"starter-场景启动器"两个概念支撑,底层通过Maven或Gradle的依赖管理插件实现
核心机制:父工程与BOM
spring-boot-starter-parent的继承
在传统的Maven项目中,我们需要手动指定每个依赖的版本。而在Spring Boot中,我们通常让项目继承spring-boot-starter-parent。它本身并没有包含实际的jar包,它是一个专门的POM文件,主要定义如下
- 默认编译配置:例如Java编译版本(JDK17+)、编码格式(UTF-8)
- 资源文件处理:如何处理application.properties或application.yml
- 插件配置:配置了spring-boot-maven-plugin等插件
- 最重要的:继承自spring-boot-dependencies
spring-boot-dependencies
spring-boot-starter-parent的父工程是spring-boot-dependencies,这才是Spring Boot依赖管理的真正核心
它是一个巨大的BOM文件,里面定义了几百个常用第三方库的号(如MySQL驱动、Jackson、Logback、Tomcat等),这里以spring-boot-dependencies-3.5.9.pom的部分截图作为展示:

机制原理:
当你在pom.xml中引入依赖时,如果不写<version>标签,Maven会向上查找父工程,最终在spring-boot-dependencies中找到预定义的版本。当然如果spring-boot-dependencies中没有的第三方依赖不写版本号会报找不到
实战场景:Starter机制
Spring Boot将常见的功能模块封装成Starter。Starter本质上时一个空的JAR,它只做一件事:传递依赖,这里以引入Web开发的starter为例
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
解析其过程:
- Maven解析spring-boot-starter-web.pom
- 该POM文件中定义了它所依赖的库如spirng-web,spring-webmvc,tomcat,jackson等
- 这些依赖的版本又通过父工程(BOM)统一管理
Starter机制的优点:
- 一站式购物:引入一个Starter,自动引入该功能所需的所有依赖,避免了"漏依赖"或"依赖错"的问题
- 版本兼容:Spring Boot团队已经测试过这些依赖之间的版本兼容性,确保它们能协同工作
特殊场景:不使用父工程
在某些企业级项目中,父工程可能被公司统一规定(如company-parent),无法继承spring-boot-start-parent。此时Spring Boot提供了另一种方式来引入依赖管理,通过dependencyManagement导入BOM
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>3.5.9</version>
<type>pom</type>
<scope>import</scope> <!-- 关键:import scope -->
</dependency>
</dependencies>
</dependencyManagement>
原理:
scop=import告诉Maven:将spring-boot-dependencies中<dependencyManagement>部分全部拷贝并合并到当前项目的<dependencyManagement>中,这样即使没有继承关系,也能享受到版本仲裁功能
版本覆盖与修改机制
虽然Spring Boot帮我们管理了版本,但如果确实需要使用特定版本(如旧版本的MySQL驱动),可以覆盖默认版本
方法一:直接指定版本(就近原则)
在当前项目pom.xml文件直接写上<version>。根据Maven的依赖调解原则-"就近原则",当前项目定义的版本优先级高于父工程定义的版本
方法二:修改属性(推荐)
spring-boot-dependencies将所有版本号都提取成了Maven属性,如果修改版本的依赖已被提取成Maven属性了,只需在自己pom.xml的<properties>中重写该属性即可
示例:修改mysql驱动版本
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<mysql.version>9.4.0</mysql.version>
</properties>
<dependencies>
<!--maven就近原则-->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<!-- <version>9.4.0</version>-->
</dependency>
<!-- 第三方依赖需要自行声明好,否则会报找不到 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.27</version>
<scope>compile</scope>
</dependency>
<!-- web开发的场景启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
SpringBoot-自动配置机制
Spring Boot的自动配置机制是其"开箱即用"特性的核心灵魂。它旨在通过"约定大于配置"的思想,根据项目中的依赖和配置,自动推测并装配应用程序所需的Bean
Spring Boot会检测你的classpath下有什么jar包,然后自动帮你把相关的配置做好
核心入口:@SpringBootApplication
一切的起点都在启动类上的@SpringBootApplication注解。这个注解是一个组合注解,核心包含以下三个部分

- @SpringBootConfiguration:表示这是一个配置类
- @EnableAutoConfiguration:核心-开启自动配置
- @ComponentScan:开启组件扫描
核心机制:@EnableAutoConfiguration的运作流程
这个注解通过@Import导入了一个关键的选择器:AutoConfigurationImportSelector,它作用流程如下:

1.加载候选配置类(读取文件)
当Spring Boot启动时,AutoConfigurationImportSelector会去读取classpath下所有的jar包中的特定文件。
特定文件路径为:META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
在这个文件中列出来所有可能需要自动配置的类的全限定名


注:此时只是读取了名单,并没有真正创建Bean
2.条件过滤(按需装配)
拿到候选名单后,Spring Boot会根据一系列条件注解进行筛选。只有满足条件的配置类才会生效。这是自动配置最核心的逻辑
这里列举一些常见的条件注解:
| 条件注解 | 作用 | 示例 |
|---|---|---|
| @ConditionalOnClass | classpath中存在指定的类时生效 | 只有引入了spring-webmvc的包,WebMvcAutoConfiguration才生效 |
| @ConditionalOnMissingBean | 容器中不存在指定的Bean时生效 | 如果你自己定义了一个DataSource,Spring Boot就不会再自动配置默认的数据源 |
| @ConditionalOnProperty | 配置文件中存在特定属性时生效 | 只有在application.yml中配置了相关属性,才会触发某些配置 |
| @ConditionalOnWebApplication | 当前时Web应用时生效 | 只有在Web环境下才会配置Servlet相关的Bean |
3.注册Bean
通过帅选的配置类会被Spring加载,配置类中通过@Bean注解定义的方法会被执行,从而将对象注入到Spring容器中
实战案例:HttpEncodingAutoConfiguration
以HTTP编码自动配置(HttpEncodingAutoConfiguration)为例,理解其工作原理
//这里仅截取了一小部分代码,实际该配置类没有这么少的代码
// 1.这是一个配置类
@AutoConfiguration
// 2.开启属性绑定
@EnableConfigurationProperties(ServerProperties.class)
// 3.必须是Servlet Web环境
@ConditionalOnWebApplication(type = Type.SERVLET)
// 4.必须存在这个类(引入了Spring Web依赖就存在)
@ConditionalOnClass(CharacterEncodingFilter.class)
// 5.配置文件中默认enabled=true
@ConditionalOnBooleanProperty(name = "server.servlet.encoding.enabled", matchIfMissing = true)
public class HttpEncodingAutoConfiguration {
// 从配置文件中读取属性
private final Encoding properties;
public HttpEncodingAutoConfiguration(ServerProperties properties) {
this.properties = properties.getServlet().getEncoding();
}
@Bean
// 6.只有在容器中没有CharacterEncodingFilter时才创建
@ConditionalOnMissingBean
public CharacterEncodingFilter characterEncodingFilter() {
CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
filter.setEncoding(this.properties.getCharset().name());
filter.setForceRequestEncoding(this.properties.shouldForce(Encoding.Type.REQUEST));
filter.setForceResponseEncoding(this.properties.shouldForce(Encoding.Type.RESPONSE));
return filter;
}
}
- Spring Boot读取到了这个配置类
- 检查:是不是Web项目?是的(引入了web-starter)
- 检查:有没有CharacterEncodingFilter类?有的(web-starter里面有)
- 检查:配置文件里面有没有禁用编码配置?默认没禁用
- 条件通过:Spring执行characterEncodingFilter方法,场景一个Bean并注入容器
用户自定义覆盖机制
Spring Boot的自动配置非常智能,它永远以用户的配置优先
这是通过@ConditionalOnMissingBean实现的。绝大多少自动配置类在定义@Bean时都会加上这个注解。
例如:
Spring Boot默认配置了一个ObjectMapper(用于JSON序列化)。如果你在代码中自己定义了一个ObjectMapper的Bean
@Bean
public ObjectMapper objectMapper() {
// 自定义配置
return new ObjectMapper();
}
Spring Boot在执行自动配置时,发现容器中已经有了ObjectMapper,就会跳过默认配置。这就是为什么我们只需要写少量代码就能覆盖默认行为的原因
属性绑定:配置文件如何生效?
自动配置类通常配合@EnableConfigurationProperties和@ConfigurationProperties使用
这里以ServerProperties属性类为例

先通过@ConfigurationProperties注解,将外部配置(如application.yml或application.properties)绑定到ServerProperties的字段上

之后用@EnableConfigurationProperties注解将ServerProperties类显示注册到容器中

浙公网安备 33010602011771号