Appearance
SpringBoot 学习笔记
导航目录
- 1. SpringBoot 概述
- 2. SpringBoot 快速入门
- 3. SpringBoot 场景启动器
- 4. SpringBoot 配置文件详解
- 5. @ConfigurationProperties 注解详解
- 6. @SpringBootApplication 注解详解
- 7. 自动配置原理
- 8. 自定义启动器开发
- 9. SpringBoot 日志应用
- 10. SpringBoot 整合与进阶(Redis/Cache)
- 11. 安全与监控(Security/Actuator)
- 12. 环境配置与部署(Cloud Native)
- 13. 单元测试深度应用
- 14. Spring Boot 3.x 核心变化
- 15. Web 核心开发细节
- 16. 任务调度与异步处理
- 17. 数据库版本管理(Flyway/Liquibase)
- 18. Modern Spring Boot 3.2+ 特性(Virtual Threads/RestClient)
- 19. 其他特性
1. SpringBoot 概述
1.1 SpringBoot 简介
Spring Boot 是由 Pivotal 团队提供的全新框架,旨在简化基于 Spring 框架的开发。它通过提供开箱即用的配置、自动配置和依赖管理等功能,使得开发者能够快速构建独立的、生产级别的基于 Spring 的应用程序。
设计理念
- 约定优于配置:遵循最佳实践,默认情况下使用推荐的设置,只有当需要自定义行为时才进行显式配置
- 易于上手:降低了学习曲线,即使是对 Spring 不熟悉的开发者也能迅速掌握并开始开发工作
- 模块化设计:允许开发者根据实际需求选择性地引入特定功能模块,避免不必要的依赖
适用场景
- 微服务架构:Spring Boot 非常适合构建微服务,简化服务集成,容易与 Spring Cloud 结合
- RESTful API 开发:内置对构建 RESTful Web 服务的支持,配合 Spring MVC 轻松创建高效 API
- 企业级应用开发:凭借强大的生态系统和丰富的插件,成为开发复杂业务逻辑的理想选择
- 快速原型开发:快速启动能力和简洁配置使其成为理想的快速迭代开发平台
1.2 SpringBoot 特性
核心特性
- 自动化配置:提供大量"开箱即用"的默认配置选项,减少手动配置工作量
- 启动器依赖:将常见库组合在一起,预设合理版本号,如
spring-boot-starter-web - 内嵌容器:支持直接嵌入 Tomcat、Jetty 或 Undertow 等 Servlet 容器
- 开发工具:包括热部署、自动重启等特性,提高开发效率
优势
- 提高生产力:减少样板代码和简化配置,专注于业务逻辑实现
- 社区支持广泛:拥有庞大开发者社区和技术文档资源
- 持续更新发展:不断改进完善,紧跟技术潮流
总结:简化开发、简化配置、简化整合、简化部署、简化监控、简化运维
2. SpringBoot 快速入门
2.1 创建 SpringBoot 项目
- 新建工程,导入启动器依赖:
xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>- 编写配置文件
application.properties:
properties
# 数据库配置
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/demo?useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root
# MyBatis 配置
mybatis.mapper-locations=classpath:mappers/*.xml
mybatis.configuration.map-underscore-to-camel-case=true
# 服务器配置
server.port=8080
server.servlet.context-path=/
spring.web.resources.static-locations=classpath:/static/- 创建启动类:
java
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}3. SpringBoot 场景启动器
3.1 启动器概念
Spring Boot 场景启动器(Starter)是简化依赖管理和配置的方式,包含构建特定类型应用程序所需的所有依赖项和自动配置。
命名规范:
- 官方启动器:
spring-boot-starter-* - 第三方启动器:
*-spring-boot-starter
3.2 启动器作用
- 父工程管理:所有 SpringBoot 项目都继承
spring-boot-starter-parent,定义了大量 jar 包及版本号 - 基启动器:每个场景启动器都导入
spring-boot-starter,包含基础依赖 - 配置管理:包含默认配置信息、属性类和配置类
3.3 常用场景启动器
xml
<!-- 基启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- Web 启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- MyBatis 启动器 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>3.4 启动器工作原理
- 属性类 (
****Properties):配置文件信息读取到这些类作为属性值存储 - 配置类 (
****Configuration):读取属性类信息,动态判断配置是否生效 - 配置优先级:应用配置 > 启动器默认配置
- 设计原则:约定大于配置
4. SpringBoot 配置文件详解
4.1 配置文件类型
SpringBoot 支持:
application.properties(优先级最高)application.ymlapplication.yaml(优先级最低)
4.2 YAML 语法
yaml
# 键值对
key: value
# 多级配置
spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb
username: root
password: secret
# 数组和列表
myapp:
servers:
- server1.example.com
- server2.example.com
- server3.example.com
# 或使用方括号
myapp:
servers: [server1.example.com, server2.example.com, server3.example.com]4.3 读取配置
使用 @Value 注解:
java
@Value("${jdbc.datasource.url}")
private String url;使用 @ConfigurationProperties:
java
@Component
@ConfigurationProperties(prefix = "jdbc.datasource")
@Data
public class JdbcProperty {
private String driverClassName;
private String url;
private String username;
private String password;
}5. @ConfigurationProperties 注解详解
5.1 基本使用
定义属性类:
java
@Component
@ConfigurationProperties(prefix = "jdbc.datasource")
@Data
public class JdbcProperty {
private String driverClassName;
private String url;
private String username;
private String password;
}在配置类中使用:
java
@Configuration
public class MybatisConfig {
@Autowired
private JdbcProperty jdbcProperty;
@Bean
public DataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(jdbcProperty.getDriverClassName());
dataSource.setUrl(jdbcProperty.getUrl());
dataSource.setUsername(jdbcProperty.getUsername());
dataSource.setPassword(jdbcProperty.getPassword());
return dataSource;
}
}5.2 注意事项
- 添加
spring-boot-configuration-processor依赖启用配置处理 - 通过
@Component或@EnableConfigurationProperties注册为 Bean - 可为属性设置默认值
- 敏感信息建议加密存储
6. @SpringBootApplication 注解详解
6.1 注解组成
@SpringBootApplication 是三个注解的组合:
@SpringBootConfiguration:标识为配置类@EnableAutoConfiguration:启用自动配置机制@ComponentScan:自动扫描并注册组件
6.2 自定义配置
自定义扫描包:
java
@SpringBootApplication(scanBasePackages = {"com.example.package1", "com.example.package2"})排除自动配置:
java
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})7. 自动配置原理(底层源码级)
SpringBoot 的核心灵魂是 自动配置(Auto-configuration)。
7.1 核心机制
- @EnableAutoConfiguration:开启自动配置的关键注解。
- AutoConfigurationImportSelector:负责异步导入自动配置类。
- Condition(条件装配):SpringBoot 根据当前类路径下的 Jar 包、Bean 的存在情况,决定是否加载某个配置类。
7.2 加载路径的变化(重点)
- SpringBoot 2.x:主要通过
META-INF/spring.factories文件加载。 - SpringBoot 3.x:推荐通过
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件加载。这是为了提高扫描性能并符合 Java 模块化趋势。
7.3 自动配置过程
- 启动阶段:
SpringApplication.run()执行。 - 收集配置:利用
AutoConfigurationImportSelector扫描类路径下所有包含自动配置说明的文件。 - 过滤筛选:根据 @ConditionalOnXXX 注解进行过滤。
@ConditionalOnClass:类路径下有指定的类才生效。@ConditionalOnMissingBean:容器中没有指定的 Bean 才生效。@ConditionalOnProperty:配置文件中有指定的属性才生效。
- 注入容器:将符合条件的配置类注入到 IOC 容器中,完成 Bean 的初始化。
💡 资深开发小贴士:如何排查自动配置问题?
如果你不确定某个自动配置类是否生效,可以在
application.properties中设置debug=true。启动时,控制台会打印 CONDITIONS EVALUATION REPORT,详细列出哪些配置生效了(Positive matches)以及哪些没生效(Negative matches)及其原因。
8. 自定义启动器开发
8.1 创建自定义启动器
项目结构:
spring-starter/
├── src/main/java
│ └── com/at/
│ ├── RobotProperties.java
│ ├── RobotService.java
│ ├── RobotAutoConfiguration.java
│ └── EnableRobot.java
└── src/main/resources
└── META-INF
└── spring.factories依赖配置:
xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>8.2 核心代码
属性类:
java
@ConfigurationProperties(prefix = "robot")
@Component
@Data
public class RobotProperties {
private String name;
private String age;
private String email;
}业务类:
java
@Service
public class RobotService {
@Autowired
RobotProperties robotProperties;
public String sayHello() {
return "你好:名字:【"+robotProperties.getName()+"】;年龄:【"+robotProperties.getAge()+"】";
}
}自动配置类:
java
@Import({RobotProperties.class, RobotService.class})
@Configuration
public class RobotAutoConfiguration {}启用注解:
java
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(RobotAutoConfiguration.class)
public @interface EnableRobot {}配置文件:META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
com.at.RobotAutoConfiguration8.3 使用自定义启动器
引入依赖:
xml
<dependency>
<groupId>com.at</groupId>
<artifactId>spring-starter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>启用配置:
java
@SpringBootApplication
@EnableRobot
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}配置属性:
properties
robot.name=lucy
robot.age=20
robot.email=java@at.com9. SpringBoot 日志应用
9.1 日志框架
Spring Boot 默认使用 Logback 作为日志框架,通过 SLF4J 作为日志抽象层。
9.2 日志级别
从低到高:
- TRACE
- DEBUG
- INFO
- WARN
- ERROR
设置日志级别:
properties
# 全局日志级别
logging.level.root=INFO
# 特定包日志级别
logging.level.com.example=DEBUG9.3 使用日志
使用 LoggerFactory:
java
Logger log = LoggerFactory.getLogger(TestSlf4j.class);
log.info("日志信息");使用 @Slf4j 注解:
java
@Slf4j
@SpringBootTest
public class TestSlf4j {
@Test
public void testSlf4j() {
log.info("普通信息info");
log.error("错误信息error");
}
}9.4 日志分组
properties
# 设置日志分组
logging.group.model=com.at.service,com.at.mapper
logging.group.controller=com.at.controller
# 设置分组日志级别
logging.level.model=debug
logging.level.controller=info9.5 文件输出
properties
# 设置日志文件路径
logging.file.path=/path/to/logs/
# 设置日志文件名
logging.file.name=application.log9.6 日志归档与切割
properties
# 设置单个日志文件大小
logging.logback.rollingpolicy.max-file-size=10MB
# 设置日志保存天数
logging.logback.rollingpolicy.max-history=7
# 设置总日志文件大小
logging.logback.rollingpolicy.total-size-cap=1GB9.7 切换 Log4j2
排除默认日志依赖:
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 引入 Log4j2 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>10. SpringBoot 整合与进阶(Redis/Cache)
10.1 整合 Redis
SpringBoot 提供了 spring-boot-starter-data-redis,底层默认使用 Lettuce 客户端。
依赖引入:
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>代码示例:
java
@Autowired
private StringRedisTemplate redisTemplate;
public void testRedis() {
redisTemplate.opsForValue().set("key", "value");
String value = redisTemplate.opsForValue().get("key");
}
> **💡 资深开发小贴士:Redis 序列化避坑**
>
> 默认的 `RedisTemplate` 使用 `JdkSerializationRedisSerializer`,这会导致 Redis 中的 Key/Value 包含二进制乱码。推荐使用 `StringRedisTemplate` 或自定义 `RedisTemplate` 配置 `Jackson2JsonRedisSerializer`,以保证数据的可读性。10.2 Spring Cache 缓存抽象
通过注解即可实现复杂的缓存逻辑。
启用缓存:在启动类添加 @EnableCaching。
常用注解:
@Cacheable:查询前先看缓存,有则返回,无则执行方法并存入缓存。@CacheEvict:清空缓存(常用于更新/删除操作)。@CachePut:保证方法执行,并将结果更新到缓存。
java
@Cacheable(value = "user", key = "#id")
public User getUserById(Long id) {
return userMapper.selectById(id);
}11. 安全与监控(Security/Actuator)
11.1 Spring Boot Security
引入 spring-boot-starter-security 即可开启安全防护。
基础配置:
java
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(auth -> auth
.requestMatchers("/public/**").permitAll()
.anyRequest().authenticated()
).formLogin(Customizer.withDefaults());
return http.build();
}
}11.2 Spring Boot Actuator
用于监控和管理 Spring Boot 应用。
暴露端点:
yaml
management:
endpoints:
web:
exposure:
include: "*" # 暴露所有端点(生产环境建议按需开启)常用端点:
/actuator/health:查看应用健康状态。/actuator/info:查看应用信息。/actuator/metrics:查看指标数据。/actuator/loggers:动态修改日志级别。
11.3 监控进阶:Prometheus + Grafana
Actuator 默认不直接输出 Prometheus 格式。
依赖引入:
xml
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>暴露格式:访问 /actuator/prometheus 即可获取指标数据。
核心流程:
- Prometheus:定期从应用的
/actuator/prometheus拉取数据(Pull 模式)。 - Grafana:配置 Prometheus 为数据源,通过可视化面板展示指标。
12. 环境配置与部署(Cloud Native)
12.1 Profiles 多环境配置
激活方式:
- 配置文件:
spring.profiles.active=prod - 命令行:
java -jar app.jar --spring.profiles.active=test - JVM 参数:
-Dspring.profiles.active=dev
12.2 云原生与 Docker
SpringBoot 项目可以轻松容器化。
编写 Dockerfile:
dockerfile
FROM openjdk:17-jdk-alpine
COPY target/*.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]12.3 Docker Compose 开发支持 (SB 3.1+)
SpringBoot 3.1 引入了对 Docker Compose 的原生支持,极大简化了本地开发环境搭建。
依赖引入:
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-docker-compose</artifactId>
<optional>true</optional>
</dependency>自动管理:
- 项目根目录存在
docker-compose.yml。 - 应用启动时,SpringBoot 会自动执行
docker-compose up。 - 应用停止时,SpringBoot 会自动执行
docker-compose stop。 - 自动配置连接:SpringBoot 会自动提取容器中的数据库端口,动态修改
spring.datasource.url。
12.4 外部化配置优先级(面试高频)
- 命令行参数(
--server.port=9000) - 来自
java:comp/env的 JNDI 属性 - Java 系统属性(
System.getProperties()) - 操作系统环境变量
- jar 包外部的
application-{profile}.properties - jar 包内部的
application-{profile}.properties - jar 包外部的
application.properties - jar 包内部的
application.properties
13. 单元测试深度应用
13.1 全栈测试
@SpringBootTest 会启动完整的上下文。
java
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class MyTest {
@Autowired
private TestRestTemplate restTemplate;
@Test
void testHello() {
String body = restTemplate.getForObject("/hello", String.class);
assertThat(body).isEqualTo("Hello");
}
}13.2 切片测试(Slice Testing)
只加载部分组件,速度更快。
@WebMvcTest:仅加载 Web 层(Controller、Filter)。@DataJpaTest/@MybatisTest:仅加载持久层组件。
MockBean 示例:
java
@WebMvcTest(UserController.class)
class WebLayerTest {
@MockBean
private UserService userService; // 模拟 Service 行为
@Test
void testGetUser() {
given(userService.getById(1L)).willReturn(new User("MockUser"));
// 执行 MockMvc 测试...
}
}14. Spring Boot 3.x 核心变化
SpringBoot 3.0 是一个里程碑版本,带来了重大升级。
14.1 基础依赖升级
- Java 17+:最低要求 Java 17,推荐使用 Java 21。
- Jakarta EE 9+:包名从
javax.*变更为jakarta.*(如jakarta.servlet)。
14.2 AOT 与 GraalVM
支持 AOT(Ahead-of-Time) 编译,可以将应用打包为 原生镜像(Native Image)。
- 优点:启动时间从秒级缩短到毫秒级,内存占用极低。
- 缺点:打包耗时久,且不支持反射、动态代理等动态特性(需额外配置)。
15. Web 核心开发细节
15.1 静态资源处理
SpringBoot 默认扫描以下路径:
classpath:/static/classpath:/public/classpath:/resources/classpath:/META-INF/resources/
15.2 欢迎页与 Favicon
- 欢迎页:将
index.html放入静态资源目录下即可。 - Favicon:将
favicon.ico放入静态资源目录下即可自动生效。
15.3 错误页面定制
在静态资源目录下创建 error 文件夹,根据 HTTP 状态码命名 HTML(如 404.html、5xx.html)。
16. 任务调度与异步处理
16.1 任务调度 (@Scheduled)
启用调度:在配置类或启动类添加 @EnableScheduling。
使用示例:
java
@Component
public class MyTasks {
// 每隔 5 秒执行一次
@Scheduled(fixedRate = 5000)
public void reportCurrentTime() {
log.info("当前时间: {}", LocalDateTime.now());
}
// Cron 表达式:每分钟的第 0 秒执行
@Scheduled(cron = "0 * * * * ?")
public void cronTask() {
log.info("执行定时任务...");
}
}16.2 异步处理 (@Async)
启用异步:在配置类或启动类添加 @EnableAsync。
核心配置:建议自定义线程池,避免使用默认的单线程池。
java
@Service
public class AsyncService {
@Async
public void doAsyncTask() {
log.info("异步任务开始: {}", Thread.currentThread().getName());
// 耗时操作...
}
}17. 数据库版本管理(Flyway/Liquibase)
在多人协作开发中,手动同步 SQL 脚本容易出错。SpringBoot 提供了对 Flyway 和 Liquibase 的原生支持。
17.1 使用 Flyway
依赖引入:
xml
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-mysql</artifactId>
</dependency>脚本存放:默认在 src/main/resources/db/migration。 脚本命名:V1__init_db.sql、V1.1__add_user_table.sql。
17.2 核心原理
- 启动时检查脚本。
- 将已执行的脚本 MD5 记录在
flyway_schema_history表中。 - 自动执行未执行的新脚本。
18. Modern Spring Boot 3.2+ 特性
18.1 虚拟线程 (Virtual Threads - Java 21)
这是 Spring Boot 3.2+ 最重磅的更新之一,极大地提高了 I/O 密集型应用的并发能力。
启用配置:
yaml
spring:
threads:
virtual:
enabled: true原理:开启后,Tomcat 线程池和 @Async 线程池将全部替换为 Java 21 的虚拟线程。
💡 资深开发小贴士:虚拟线程的注意事项
虚拟线程在执行
synchronized块或native方法时可能会导致线程固定(Pinning),从而降低性能。在高并发场景下,建议将synchronized替换为ReentrantLock。
18.2 RestClient (现代化的 RestTemplate)
RestClient 是 Spring Boot 3.2 引入的新一代同步 HTTP 客户端,语法更简洁,链式调用更流畅。
代码示例:
java
RestClient restClient = RestClient.create();
String result = restClient.get()
.uri("https://api.example.com/data")
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.body(String.class);19. 其他特性
19.1 Banner 定制
- 在
src/main/resources下创建banner.txt。 - 配置路径:
spring.banner.location=classpath:banner.txt。
19.2 事件驱动编程
SpringBoot 基于观察者模式实现了完善的事件机制。
- 定义事件:继承
ApplicationEvent。 - 发布事件:注入
ApplicationEventPublisher。 - 监听事件:使用
@EventListener,支持@Async异步执行。