文章目录
- 前言
-
- [1. Spring Boot核心认知:是什么与为什么](#1. Spring Boot核心认知:是什么与为什么)
-
- [1.1 定义与核心价值](#1.1 定义与核心价值)
- [1.2 与传统Spring的核心差异](#1.2 与传统Spring的核心差异)
- [1.3 版本选型与生态适配](#1.3 版本选型与生态适配)
- [2. 环境搭建:从0到1创建Spring Boot项目](#2. 环境搭建:从0到1创建Spring Boot项目)
-
- [2.1 开发环境要求](#2.1 开发环境要求)
- [2.2 三种创建方式对比](#2.2 三种创建方式对比)
- [2.3 项目结构解析(以Maven项目为例)](#2.3 项目结构解析(以Maven项目为例))
- [3. 核心原理:自动配置的"黑魔法"](#3. 核心原理:自动配置的“黑魔法”)
-
- [3.1 @SpringBootApplication注解拆解](#3.1 @SpringBootApplication注解拆解)
- [3.2 自动配置流程](#3.2 自动配置流程)
- [3.3 条件注解体系(@Conditional家族)](#3.3 条件注解体系(@Conditional家族))
- [3.4 自动配置 vs 传统Spring配置](#3.4 自动配置 vs 传统Spring配置)
- [4. 核心组件与功能实战](#4. 核心组件与功能实战)
-
- [4.1 Starter依赖:"一站式"依赖解决方案](#4.1 Starter依赖:“一站式”依赖解决方案)
- [4.2 配置文件:application.properties/yaml详解](#4.2 配置文件:application.properties/yaml详解)
- [4.3 核心注解:从Bean管理到业务开发](#4.3 核心注解:从Bean管理到业务开发)
- [4.4 Actuator:应用监控与运维](#4.4 Actuator:应用监控与运维)
- [5. 企业级实战:构建RESTful API与数据访问](#5. 企业级实战:构建RESTful API与数据访问)
-
- [5.1 实战1:开发用户管理RESTful API](#5.1 实战1:开发用户管理RESTful API)
- [5.2 实战2:整合Redis实现缓存](#5.2 实战2:整合Redis实现缓存)
-
- [步骤1:引入Redis Starter](#步骤1:引入Redis Starter)
- 步骤2:配置Redis(application.yml)
- 步骤3:开启缓存并使用
- [6. 常见问题与解决方案(表格汇总)](#6. 常见问题与解决方案(表格汇总))
- [7. 最佳实践:性能优化与规范](#7. 最佳实践:性能优化与规范)
-
- [7.1 代码结构规范](#7.1 代码结构规范)
- [7.2 性能优化技巧](#7.2 性能优化技巧)
- 总结
前言
若对您有帮助的话,请点赞收藏加关注哦,您的关注是我持续创作的动力!有问题请私信或联系邮箱:funian.gm@gmail.com
Spring Boot作为Spring生态的"简化器",通过"约定优于配置"的理念彻底改变了Java后端开发模式------无需繁琐的XML配置,无需手动整合依赖,仅需几行代码即可快速搭建一个可运行的企业级应用。本文将从核心原理、环境搭建、实战开发到问题排查,全方位解析Spring Boot,结合大量表格对比与代码实例,帮你掌握从入门到精通的完整技能链。
1. Spring Boot核心认知:是什么与为什么
1.1 定义与核心价值
Spring Boot是由Pivotal团队开发的Spring生态子项目,核心定位是"简化Spring应用开发"------通过自动配置、 starter依赖、嵌入式服务器等特性,实现"开箱即用",让开发者专注于业务逻辑而非框架配置。
其核心价值可概括为"三减一提":
- 减少配置:消除90%以上的XML配置,改用注解或少量配置文件;
- 减少依赖 :通过starter整合依赖(如
spring-boot-starter-web
包含Spring MVC+Tomcat); - 减少部署:支持嵌入式服务器(Tomcat/Jetty/Undertow),可直接打包为Jar运行;
- 提升效率:从项目创建到上线的周期缩短50%以上,支持热部署。

1.2 与传统Spring的核心差异
对比维度 | 传统Spring | Spring Boot |
---|---|---|
配置方式 | 以XML配置为主(如applicationContext.xml) | 注解配置为主(@Configuration)+自动配置 |
依赖管理 | 需手动维护各组件版本(易冲突) | Starter自动管理版本,统一依赖快照 |
服务器部署 | 需打包为War,部署到外部Tomcat | 可打包为Jar(内置服务器),直接运行 |
开发效率 | 配置繁琐,启动慢(需加载大量XML) | 零配置启动,开发周期短 |
监控能力 | 需手动集成第三方监控(如Spring Boot Actuator) | 内置Actuator,开箱即用监控端点 |
适用场景 | 复杂企业级应用(需精细配置) | 快速开发、微服务、云原生应用 |
1.3 版本选型与生态适配
Spring Boot版本分为"快照版(SNAPSHOT) ""里程碑版(M) ""正式版(RELEASE) ""长期支持版(LTS) ",企业级开发优先选择LTS版,稳定性与兼容性更有保障。
版本类型 | 特点 | 推荐度 | 适用场景 |
---|---|---|---|
SNAPSHOT | 开发中版本,不稳定,功能可能变更 | ❌ 不推荐 | 框架源码贡献者测试 |
M(Milestone) | 里程碑版,功能初步稳定,待验证 | ❌ 不推荐 | 技术预研,非生产环境 |
RELEASE | 正式版,功能稳定,但支持周期短(6-12个月) | ⭐⭐⭐ 一般推荐 | 短期项目、非核心业务 |
LTS(Long-Term Support) | 长期支持版,支持3-5年,修复安全漏洞与BUG | ⭐⭐⭐⭐⭐ 强烈推荐 | 核心业务、企业级项目、微服务集群 |
当前主流LTS版:Spring Boot 2.7.x(支持至2025年11月)、Spring Boot 3.2.x(支持至2026年11月),需注意:
- Spring Boot 3.x要求JDK 17+,且依赖Jakarta EE(而非Java EE);
- 若项目需兼容JDK 8/11,选择Spring Boot 2.7.x。
2. 环境搭建:从0到1创建Spring Boot项目
2.1 开发环境要求
工具/组件 | 版本要求 | 说明 |
---|---|---|
JDK | Spring Boot 2.x:JDK 8/11/17 Spring Boot 3.x:JDK 17+ | 推荐JDK 17(LTS版,性能更优) |
Maven | 3.6.3+ | 需配置阿里云镜像(加速依赖下载) |
Gradle | 7.5+(若用Gradle构建) | 替代Maven的构建工具,脚本更简洁 |
IDE | IntelliJ IDEA 2021.3+ / Eclipse 2022+ | IDEA对Spring Boot支持更友好 |
浏览器 | Chrome/Firefox | 用于访问Swagger/Actuator监控页面 |
Maven阿里云镜像配置(settings.xml):
xml
<mirrors>
<mirror>
<id>aliyunmaven</id>
<mirrorOf>central</mirrorOf>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
</mirrors>
2.2 三种创建方式对比
创建方式 | 步骤 | 优点 | 缺点 | 适用场景 |
---|---|---|---|---|
IDEA可视化创建 | 1. 新建项目→选择Spring Initializr 2. 填写Group/Artifact 3. 选择Starter(如Web/MySQL) 4. 选择存储路径→完成 | 操作直观,支持实时调整依赖 | 需联网,IDEA社区版功能有限 | 新手入门、Windows/macOS图形化操作 |
终端命令创建 | 1. 执行命令: curl https://start.spring.io/starter.zip -d dependencies=web,mysql -o demo.zip 2. 解压zip包 3. 用IDE打开 |
跨平台(Linux/macOS/Windows),速度快 | 需记命令,依赖选择不直观 | 服务器环境、Linux终端操作 |
start.spring.io创建 | 1. 打开官网(https://start.spring.io/) 2. 可视化配置项目信息与依赖 3. 下载zip包→解压→IDE打开 | 无需安装IDE,配置灵活 | 需手动下载,依赖冲突需手动排查 | 无IDE环境、临时快速创建项目 |
2.3 项目结构解析(以Maven项目为例)
demo/ # 项目根目录
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── example/
│ │ │ └── demo/
│ │ │ ├── DemoApplication.java # 启动类(核心入口)
│ │ │ ├── controller/ # 控制器层(处理HTTP请求)
│ │ │ ├── service/ # 服务层(业务逻辑)
│ │ │ ├── dao/ # 数据访问层(数据库操作)
│ │ │ ├── entity/ # 实体类(与数据库表映射)
│ │ │ ├── config/ # 配置类(自定义Bean/拦截器)
│ │ │ └── exception/ # 异常处理(全局异常/自定义异常)
│ │ └── resources/
│ │ ├── application.properties # 主配置文件(properties格式)
│ │ ├── application.yml # 主配置文件(yaml格式,推荐)
│ │ ├── static/ # 静态资源(CSS/JS/图片)
│ │ └── templates/ # 模板文件(Thymeleaf/Freemarker)
│ └── test/ # 测试类目录(与main结构对应)
├── pom.xml # Maven依赖配置文件
└── README.md # 项目说明文档
核心文件作用:
DemoApplication.java
:启动类,含@SpringBootApplication
注解,执行main
方法启动应用;application.yml
:全局配置文件,用于配置端口、数据库连接、日志等;pom.xml
:管理依赖(如starter、第三方组件),控制项目构建流程。
3. 核心原理:自动配置的"黑魔法"
自动配置是Spring Boot的灵魂,其核心是"根据classpath中的依赖,自动注册Bean到Spring容器",无需手动配置。
3.1 @SpringBootApplication注解拆解
@SpringBootApplication
是Spring Boot的"一站式注解",本质是三个核心注解的组合:
注解名称 | 作用 | 关键细节 |
---|---|---|
@SpringBootConfiguration | 标记类为配置类,等价于@Configuration |
支持在类中用@Bean 定义自定义Bean |
@EnableAutoConfiguration | 开启自动配置功能 | 核心注解,触发自动配置流程 |
@ComponentScan | 扫描组件(@Component/@Service/@Controller等) | 默认扫描启动类所在包及其子包 |
注解等效代码:
java
// @SpringBootApplication 等效于以下三个注解
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(basePackages = "com.example.demo") // 默认扫描启动类所在包
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
3.2 自动配置流程
- 扫描自动配置类 :Spring Boot启动时,
@EnableAutoConfiguration
会加载META-INF/spring.factories
文件,该文件中定义了所有自动配置类(如DataSourceAutoConfiguration
、WebMvcAutoConfiguration
); - 条件匹配 :自动配置类通过
@Conditional
家族注解判断是否生效(如@ConditionalOnClass
判断classpath是否有指定类); - 注册Bean :满足条件的自动配置类会将核心Bean(如
DataSource
、DispatcherServlet
)注册到Spring容器; - 配置绑定 :通过
@ConfigurationProperties
将application.yml
中的配置(如spring.datasource.url
)绑定到自动配置类的属性上。
示例:DataSourceAutoConfiguration生效条件:
java
// 仅当classpath中有DataSource.class且容器中无DataSource Bean时生效
@ConditionalOnClass(DataSource.class)
@ConditionalOnMissingBean(type = "javax.sql.DataSource")
public class DataSourceAutoConfiguration {
// 绑定application.yml中的spring.datasource配置
@ConfigurationProperties(prefix = "spring.datasource")
public DataSourceProperties properties() {
return new DataSourceProperties();
}
// 注册DataSource Bean
@Bean
public DataSource dataSource(DataSourceProperties properties) {
return properties.initializeDataSourceBuilder().build();
}
}
3.3 条件注解体系(@Conditional家族)
@Conditional
是自动配置的"开关",通过判断环境、类存在性、Bean存在性等决定配置是否生效:
条件注解 | 作用 | 示例场景 |
---|---|---|
@ConditionalOnClass | 当classpath中有指定类时生效 | 有Servlet.class 才加载Web相关配置 |
@ConditionalOnMissingClass | 当classpath中无指定类时生效 | 无RedisTemplate.class 才加载默认缓存配置 |
@ConditionalOnBean | 当容器中有指定Bean时生效 | 有RedisConnectionFactory 才注册RedisTemplate |
@ConditionalOnMissingBean | 当容器中无指定Bean时生效 | 无自定义DataSource 才注册默认数据源 |
@ConditionalOnProperty | 当配置文件中有指定属性时生效 | 配置spring.mvc.enable=true 才加载MVC配置 |
@ConditionalOnWebApplication | 当应用是Web应用时生效 | 加载DispatcherServlet、WebMvcConfigurer |
@ConditionalOnNotWebApplication | 当应用不是Web应用时生效 | 加载非Web相关的Bean(如定时任务) |
3.4 自动配置 vs 传统Spring配置
配置场景 | 传统Spring配置(XML) | Spring Boot自动配置 | 代码/配置量对比 |
---|---|---|---|
配置数据源 | 需定义DataSource 、SqlSessionFactory 等Bean(约50行XML) |
仅需在application.yml配置spring.datasource (约5行) |
10:1(自动配置更简洁) |
配置Spring MVC | 需配置DispatcherServlet 、视图解析器等(约30行XML) |
引入spring-boot-starter-web 自动生效,无需额外配置 |
30:0(自动配置零代码) |
配置事务管理 | 需配置TransactionManager 、开启事务注解(约20行XML) |
引入spring-boot-starter-jdbc 后,加@Transactional 即可 |
20:1(仅需注解) |
配置日志 | 需配置logback.xml (约20行) |
引入spring-boot-starter-logging 自动生效,支持简单配置 |
20:2(仅需配置日志级别) |
4. 核心组件与功能实战
4.1 Starter依赖:"一站式"依赖解决方案
Starter是Spring Boot的"依赖打包"机制------将某一领域的所有依赖(如Web开发、数据访问)整合为一个starter,开发者仅需引入一个依赖即可使用所有功能,无需手动管理依赖版本。
常用Starter对比:
Starter名称 | 核心功能 | 包含的关键依赖 | 适用场景 |
---|---|---|---|
spring-boot-starter-web | Web开发(Spring MVC+嵌入式服务器) | spring-web、spring-webmvc、tomcat-embed-core | 开发RESTful API、Web应用 |
spring-boot-starter-data-jpa | 整合JPA(ORM框架) | spring-data-jpa、hibernate-core、hikariCP | 简化数据库CRUD,支持自动生成SQL |
spring-boot-starter-mybatis | 整合MyBatis(持久层框架) | mybatis、mybatis-spring、spring-jdbc | 复杂SQL场景(动态SQL、存储过程) |
spring-boot-starter-redis | 整合Redis(缓存/分布式锁) | spring-data-redis、lettuce-core | 缓存热点数据、分布式锁、限流器 |
spring-boot-starter-security | 安全认证与授权(登录/权限控制) | spring-security-web、spring-security-config | 用户登录、API权限控制 |
spring-boot-starter-actuator | 应用监控(健康检查/指标统计) | spring-boot-actuator、micrometer-core | 运维监控、应用健康检查 |
spring-boot-starter-test | 单元测试与集成测试 | junit、mockito、spring-test | 测试Service/Controller层代码 |
使用示例:在pom.xml中引入Web Starter,即可开发Web应用:
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
4.2 配置文件:application.properties/yaml详解
Spring Boot支持两种配置文件格式:application.properties
(键值对)和application.yml
(缩进式,推荐),核心作用是"外部化配置"------将配置与代码分离,便于不同环境(开发/测试/生产)切换。
配置优先级(从高到低)
- 命令行参数(如
java -jar demo.jar --server.port=8081
); - 系统环境变量(如
SPRING_DATASOURCE_URL
); application-{profile}.yml
(如application-prod.yml
,激活指定环境);application.yml
(主配置文件);application.properties
(主配置文件,优先级低于yml);- 内置默认配置(Spring Boot默认值)。
多环境配置实战
-
创建多环境配置文件:
application-dev.yml
:开发环境(端口8080,连接本地MySQL);application-test.yml
:测试环境(端口8081,连接测试MySQL);application-prod.yml
:生产环境(端口80,连接生产MySQL,开启HTTPS)。
-
激活指定环境:
-
方式1:在
application.yml
中配置(全局生效):yamlspring: profiles: active: dev # 激活开发环境
-
方式2:命令行激活(临时生效):
bashjava -jar demo.jar --spring.profiles.active=prod
-
常用配置示例(application.yml)
yaml
# 1. 服务器配置
server:
port: 8080 # 端口
servlet:
context-path: /demo # 上下文路径(访问前缀)
# 2. 数据库配置(MySQL)
spring:
datasource:
url: jdbc:mysql://localhost:3306/demo_db?useSSL=false&serverTimezone=UTC
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
hikari:
maximum-pool-size: 10 # 连接池最大连接数
connection-timeout: 30000 # 连接超时时间(毫秒)
# 3. MyBatis配置
mybatis:
mapper-locations: classpath:mapper/**/*.xml # Mapper XML文件路径
type-aliases-package: com.example.demo.entity # 实体类包路径
configuration:
map-underscore-to-camel-case: true # 下划线转驼峰(如user_name→userName)
# 4. 日志配置
logging:
level:
root: INFO # 全局日志级别
com.example.demo.dao: DEBUG # DAO层日志级别(打印SQL)
file:
name: logs/demo.log # 日志文件路径
# 5. Redis配置
redis:
host: localhost
port: 6379
password:
lettuce:
pool:
max-active: 8 # 最大活跃连接数
max-idle: 4 # 最大空闲连接数
4.3 核心注解:从Bean管理到业务开发
Spring Boot基于注解驱动开发,核心注解可分为"Bean管理注解 ""业务开发注解 ""配置注解"三类:
注解分类 | 注解名称 | 作用 | 示例代码 |
---|---|---|---|
Bean管理 | @Component | 标记普通组件(通用Bean) | @Component public class UserUtils {} |
@Service | 标记服务层组件(业务逻辑) | @Service public class UserService {} |
|
@Controller | 标记控制器组件(处理HTTP请求) | @Controller public class UserController {} |
|
@Repository | 标记数据访问层组件(DAO) | @Repository public class UserDao {} |
|
@Bean | 在配置类中定义Bean(第三方组件) | @Bean public RedisTemplate redisTemplate() {} |
|
业务开发 | @Autowired | 依赖注入(按类型) | @Autowired private UserService userService; |
@Resource | 依赖注入(按名称,JDK原生) | @Resource(name = "userService") private UserService userService; |
|
@RequestMapping | 映射HTTP请求(通用) | @RequestMapping("/users") |
|
@GetMapping | 映射GET请求(简化版) | @GetMapping("/users/{id}") |
|
@PostMapping | 映射POST请求(简化版) | @PostMapping("/users") |
|
@Transactional | 开启事务管理 | @Transactional public void saveUser(User user) {} |
|
配置注解 | @Configuration | 标记配置类 | @Configuration public class RedisConfig {} |
@ConfigurationProperties | 绑定配置文件属性 | @ConfigurationProperties(prefix = "spring.datasource") |
|
@Value | 注入单个配置属性(简单值) | @Value("${server.port}") private int port; |
4.4 Actuator:应用监控与运维
Actuator是Spring Boot的"运维工具",通过暴露HTTP端点(如/actuator/health
、/actuator/metrics
),提供应用健康检查、指标统计、环境配置等功能,无需手动开发监控系统。
核心端点对比
端点路径 | 作用 | 权限控制 | 适用场景 |
---|---|---|---|
/actuator/health | 应用健康状态(UP/DOWN/OUT_OF_SERVICE) | 无需认证(默认) | 运维监控(如Prometheus/Grafana) |
/actuator/metrics | 应用指标(JVM内存/CPU/请求数) | 无需认证(默认) | 性能排查(如内存泄漏、CPU过高) |
/actuator/env | 环境配置(系统变量/配置文件) | 需认证(敏感信息) | 配置排查(如确认配置是否生效) |
/actuator/beans | 容器中所有Bean信息 | 需认证(敏感信息) | 开发排查(如Bean是否注册成功) |
/actuator/loggers | 日志级别管理(动态调整) | 需认证(敏感操作) | 线上排查(无需重启调整日志级别) |
/actuator/shutdown | 优雅关闭应用 | 需认证+开启(默认关闭) | 线上部署(避免强制kill导致数据丢失) |
启用Actuator实战
-
引入依赖:
xml<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
-
配置端点(application.yml):
yamlmanagement: endpoints: web: exposure: include: health,metrics,env,loggers # 暴露的端点 endpoint: health: show-details: always # 显示健康详情(如数据库连接状态) shutdown: enabled: true # 开启优雅关闭端点
-
访问端点:
- 健康检查:
http://localhost:8080/demo/actuator/health
- 指标统计:
http://localhost:8080/demo/actuator/metrics/http.server.requests
- 健康检查:
5. 企业级实战:构建RESTful API与数据访问
5.1 实战1:开发用户管理RESTful API
步骤1:定义实体类(User.java)
java
package com.example.demo.entity;
import lombok.Data;
import javax.persistence.*;
@Data // Lombok注解,自动生成getter/setter/toString
@Entity // JPA注解,标记为数据库实体
@Table(name = "t_user") // 映射数据库表t_user
public class User {
@Id // 主键
@GeneratedValue(strategy = GenerationType.IDENTITY) // 自增主键
private Long id;
@Column(name = "username", nullable = false, unique = true) // 用户名(非空+唯一)
private String username;
@Column(name = "password", nullable = false) // 密码(非空)
private String password;
@Column(name = "email") // 邮箱(可选)
private String email;
}
步骤2:数据访问层(UserRepository.java)
java
package com.example.demo.dao;
import com.example.demo.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.Optional;
@Repository
// JpaRepository<User, Long>:泛型1=实体类,泛型2=主键类型,提供CRUD默认方法
public interface UserRepository extends JpaRepository<User, Long> {
// 自定义查询方法(JPA自动生成SQL:SELECT * FROM t_user WHERE username = ?)
Optional<User> findByUsername(String username);
}
步骤3:服务层(UserService.java)
java
package com.example.demo.service;
import com.example.demo.dao.UserRepository;
import com.example.demo.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Optional;
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
// 查询所有用户
public List<User> findAll() {
return userRepository.findAll();
}
// 根据ID查询用户
public Optional<User> findById(Long id) {
return userRepository.findById(id);
}
// 新增/修改用户(含事务)
@Transactional // 开启事务,异常时回滚
public User save(User user) {
return userRepository.save(user);
}
// 根据ID删除用户
@Transactional
public void deleteById(Long id) {
userRepository.deleteById(id);
}
// 根据用户名查询用户
public Optional<User> findByUsername(String username) {
return userRepository.findByUsername(username);
}
}
步骤4:控制器层(UserController.java)
java
package com.example.demo.controller;
import com.example.demo.entity.User;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Optional;
@RestController // @Controller + @ResponseBody(返回JSON)
@RequestMapping("/api/users") // 统一URL前缀
public class UserController {
@Autowired
private UserService userService;
// 1. 查询所有用户(GET /api/users)
@GetMapping
public List<User> findAll() {
return userService.findAll();
}
// 2. 根据ID查询用户(GET /api/users/{id})
@GetMapping("/{id}")
public ResponseEntity<User> findById(@PathVariable Long id) {
Optional<User> user = userService.findById(id);
// 存在则返回200+用户信息,不存在则返回404
return user.map(ResponseEntity::ok)
.orElseGet(() -> ResponseEntity.notFound().build());
}
// 3. 新增用户(POST /api/users)
@PostMapping
public ResponseEntity<User> save(@RequestBody User user) {
User savedUser = userService.save(user);
// 返回201(创建成功)+新增用户信息+Location头(用户URL)
return ResponseEntity.status(HttpStatus.CREATED)
.body(savedUser);
}
// 4. 修改用户(PUT /api/users/{id})
@PutMapping("/{id}")
public ResponseEntity<User> update(@PathVariable Long id, @RequestBody User user) {
// 验证用户是否存在
if (!userService.findById(id).isPresent()) {
return ResponseEntity.notFound().build();
}
user.setId(id); // 确保修改的是指定ID的用户
User updatedUser = userService.save(user);
return ResponseEntity.ok(updatedUser);
}
// 5. 删除用户(DELETE /api/users/{id})
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteById(@PathVariable Long id) {
if (!userService.findById(id).isPresent()) {
return ResponseEntity.notFound().build();
}
userService.deleteById(id);
return ResponseEntity.noContent().build(); // 返回204(无内容)
}
}
步骤5:测试API(用Postman)
API接口 | 请求方法 | 请求体示例 | 响应状态 |
---|---|---|---|
/api/users | GET | 无 | 200 + 用户列表JSON |
/api/users/1 | GET | 无 | 200 + 用户详情JSON(存在)/404(不存在) |
/api/users | POST | {"username":"test","password":"123","email":"test@xxx.com"} |
201 + 新增用户JSON |
/api/users/1 | PUT | {"username":"test","password":"456","email":"test@xxx.com"} |
200 + 修改后用户JSON |
/api/users/1 | DELETE | 无 | 204(成功)/404(不存在) |
5.2 实战2:整合Redis实现缓存
步骤1:引入Redis Starter
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
</dependency>
步骤2:配置Redis(application.yml)
yaml
spring:
redis:
host: localhost
port: 6379
password: # 无密码则留空
lettuce:
pool:
max-active: 8 # 最大活跃连接数
max-idle: 4 # 最大空闲连接数
min-idle: 2 # 最小空闲连接数
timeout: 3000 # 连接超时时间(毫秒)
步骤3:开启缓存并使用
java
// 1. 在启动类添加@EnableCaching开启缓存
@SpringBootApplication
@EnableCaching
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
// 2. 在Service方法添加@Cacheable(查询缓存)、@CachePut(更新缓存)、@CacheEvict(删除缓存)
@Service
public class UserService {
// 查询用户时先查缓存,无缓存则查数据库并写入缓存
@Cacheable(value = "userCache", key = "#id")
public Optional<User> findById(Long id) {
System.out.println("从数据库查询用户:" + id); // 验证缓存是否生效
return userRepository.findById(id);
}
// 修改用户后更新缓存(确保缓存与数据库一致)
@CachePut(value = "userCache", key = "#user.id")
@Transactional
public User save(User user) {
return userRepository.save(user);
}
// 删除用户后删除缓存(避免缓存脏数据)
@CacheEvict(value = "userCache", key = "#id")
@Transactional
public void deleteById(Long id) {
userRepository.deleteById(id);
}
}
测试缓存生效:
- 第一次调用
findById(1)
:控制台打印"从数据库查询用户:1",数据写入Redis; - 第二次调用
findById(1)
:控制台无打印,直接从Redis返回数据(缓存生效)。
6. 常见问题与解决方案(表格汇总)
问题现象 | 可能原因 | 解决方案 |
---|---|---|
启动报错:Port 8080 was already in use | 8080端口被其他进程占用 | 1. 关闭占用进程:lsof -i :8080 找到PID,kill -9 PID 2. 修改端口:在application.yml配置server.port=8081 |
自动配置失效(如DataSource未注册) | 1. 未引入对应starter(如spring-boot-starter-jdbc) 2. 配置文件属性写错(如spring.datasouce.url 少个s ) |
1. 检查pom.xml是否引入正确starter 2. 核对配置属性名(参考Spring Boot官方文档) |
依赖冲突(如ClassNotFoundException) | 1. 多个依赖包含相同类但版本不同 2. Maven依赖传递导致版本冲突 | 1. 用mvn dependency:tree 分析依赖树 2. 排除冲突依赖: <exclusions><exclusion><groupId>xxx</groupId><artifactId>xxx</artifactId></exclusion></exclusions> |
事务不生效(@Transactional无效) | 1. 方法不是public(@Transactional仅对public方法生效) 2. 自调用(同一类中方法调用,AOP无法拦截) 3. 异常被捕获(未抛出异常,事务无法回滚) | 1. 确保方法为public 2. 注入自身Bean调用(如@Autowired private UserService self; self.save(user); ) 3. 捕获异常后重新抛出:throw new RuntimeException(e); |
Redis缓存不生效 | 1. 未添加@EnableCaching 2. 方法参数不是Serializable(缓存key需序列化) 3. 缓存注解属性错误(如key表达式写错) | 1. 在启动类添加@EnableCaching 2. 确保参数实现Serializable接口 3. 核对key表达式(如#id 对应方法参数id) |
7. 最佳实践:性能优化与规范
7.1 代码结构规范
规范点 | 具体要求 | 示例 |
---|---|---|
包命名 | 全小写,按功能分层:com.公司名.项目名.分层 |
com.example.demo.controller 、com.example.demo.service |
类命名 | 首字母大写,驼峰式,后缀明确: Controller:XXXController Service:XXXService DAO:XXXRepository/XXXDao | UserController 、UserService 、UserRepository |
方法命名 | 首字母小写,驼峰式,动词+名词: 查询:get/find/query 新增:save/add/create 修改:update 删除:delete/remove | findById() 、saveUser() 、deleteById() |
变量命名 | 首字母小写,驼峰式,避免拼音,见名知意 | userId (而非yonghuming )、userList (而非list ) |
7.2 性能优化技巧
优化点 | 具体做法 | 效果提升 |
---|---|---|
连接池优化 | 1. 数据库连接池:HikariCP(默认)配置maximum-pool-size=10-20 2. Redis连接池:Lettuce配置max-active=8 |
减少连接创建开销,提升并发能力30%+ |
JVM调优 | 1. 设置堆内存:-Xms2g -Xmx2g (初始=最大,避免扩容) 2. 使用G1垃圾收集器:-XX:+UseG1GC |
减少GC停顿时间,提升系统稳定性 |
缓存优化 | 1. 热点数据缓存(如首页商品列表) 2. 设置合理缓存过期时间(如1小时) 3. 避免缓存穿透(布隆过滤器) | 减少数据库访问量,接口响应速度提升10-100倍 |
日志优化 | 1. 线上环境日志级别设为INFO(避免DEBUG日志) 2. 日志文件按天切割(避免单个文件过大) 3. 禁用System.out.println(同步打印,性能差) | 减少磁盘I/O,提升系统吞吐量20%+ |
总结
Spring Boot的核心优势在于"简化开发、提升效率"------通过自动配置消除繁琐配置,通过starter整合依赖,通过嵌入式服务器简化部署,让开发者从"框架配置"回归"业务逻辑"。本文从原理到实战,覆盖了Spring Boot的核心知识点:
- 原理层:理解自动配置的"扫描→匹配→生效"流程,掌握@Conditional条件注解的作用;
- 实战层:会用starter依赖、配置文件、Actuator,能开发RESTful API并整合数据库/Redis;
- 问题层:能定位并解决端口冲突、依赖冲突、事务不生效等常见问题;
- 规范层:遵循代码结构与性能优化最佳实践,开发可维护、高性能的应用。