Spring Boot 核心知识点总结

Spring Boot 核心知识点总结


一、Spring Boot 分层架构

1.1 三层架构

markdown 复制代码
┌─────────────────────────────────┐
│   Controller 层(接口层)          │  ← 接收请求、返回响应
└─────────────────────────────────┘
              ↓
┌─────────────────────────────────┐
│   Service 层(业务逻辑层)         │  ← 处理业务规则、数据转换
└─────────────────────────────────┘
              ↓
┌─────────────────────────────────┐
│   Repository 层(数据访问层)      │  ← 操作数据库
└─────────────────────────────────┘

1.2 各层职责

层级 职责 关键注解
Controller 接收 HTTP 请求、参数校验、调用 Service、返回响应 @RestController, @RequestMapping, @PostMapping
Service 业务规则、数据转换、事务管理、异常处理 @Service, @Transactional
Repository 操作数据库、基本 CRUD、自定义查询 @Repository

二、核心注解详解

2.1 实体类注解

@Entity
  • 作用: 标记这是一个 JPA 实体类,对应数据库表
  • 位置: 实体类上方
  • 示例:
java 复制代码
@Entity
public class Article {
    // ...
}
@Table
  • 作用: 指定数据库表名
  • 位置: 实体类上方
  • 参数: name - 表名
  • 示例:
java 复制代码
@Entity
@Table(name = "articles")
public class Article {
    // ...
}
@Id
  • 作用: 标记主键字段
  • 位置: 主键字段上方
  • 示例:
java 复制代码
@Id
private Long id;
@GeneratedValue
  • 作用: 主键生成策略
  • 位置: 主键字段上方
  • 策略类型:
    • GenerationType.IDENTITY - 自增(MySQL、H2)
    • GenerationType.AUTO - 自动选择
    • GenerationType.SEQUENCE - 序列(Oracle)
    • GenerationType.TABLE - 表生成
  • 示例:
java 复制代码
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

2.2 控制器注解

@RestController
  • 作用: 标记这是一个 RESTful API 控制器
  • 原理: @RestController = @Controller + @ResponseBody
  • 效果: 所有方法的返回值自动转换为 JSON
  • 位置: 控制器类上方
  • 示例:
java 复制代码
@RestController
public class ArticleController {
    // ...
}
@RequestMapping
  • 作用: 定义基础 URL 路径
  • 位置: 类或方法上方
  • 参数:
    • value/path - 路径
    • method - HTTP 方法(可选)
  • 示例:
java 复制代码
@RestController
@RequestMapping("/article")
public class ArticleController {
    // 所有方法的路径都以 /article 开头
}
@PostMapping
  • 作用: 定义 POST 请求映射
  • 位置: 方法上方
  • 示例:
java 复制代码
@PostMapping("/add")
public ArticleResponse addArticle(@RequestBody ArticleAddRequest request) {
    // 处理 POST /article/add 请求
}

类似注解:

  • @GetMapping - GET 请求
  • @PutMapping - PUT 请求
  • @DeleteMapping - DELETE 请求
  • @PatchMapping - PATCH 请求
@RequestBody
  • 作用: 将请求体(JSON)转换为 Java 对象
  • 位置: 方法参数前
  • 示例:
java 复制代码
@PostMapping("/add")
public ArticleResponse addArticle(@RequestBody ArticleAddRequest request) {
    // JSON → Java 对象
}
@ResponseBody
  • 作用: 将返回值转换为 JSON 响应
  • 位置: 方法上方
  • 说明: @RestController 已包含此注解,无需单独使用

2.3 Service 注解

@Service
  • 作用: 标记这是一个服务类
  • 位置: Service 类上方
  • 效果: Spring 会自动扫描并创建实例
  • 示例:
java 复制代码
@Service
public class ArticleService {
    // ...
}
@Transactional
  • 作用: 开启事务管理
  • 位置: 类或方法上方
  • 效果: 保证数据库操作的原子性(要么全部成功,要么全部失败)
  • 示例:
java 复制代码
@Service
@Transactional
public class ArticleService {
    // 所有方法都在事务中执行
}

事务传播行为:

  • REQUIRED(默认) - 如果有事务就加入,没有就新建
  • REQUIRES_NEW - 总是新建事务
  • SUPPORTS - 有事务就加入,没有就非事务执行

2.4 依赖注入注解

@Autowired
  • 作用: 自动注入依赖对象
  • 位置: 字段、构造方法、Setter 方法
  • 原理: Spring 自动查找并注入匹配的对象
  • 示例:
java 复制代码
@Service
public class ArticleService {
    
    @Autowired
    private ArticleRepository articleRepository;
    
    // 不需要手动 new ArticleRepository()
}

2.5 异常处理注解

@RestControllerAdvice
  • 作用: 全局异常处理(RESTful)
  • 位置: 异常处理类上方
  • 原理: @RestControllerAdvice = @ControllerAdvice + @ResponseBody
  • 示例:
java 复制代码
@RestControllerAdvice
public class GlobalExceptionHandler {
    // ...
}
@ExceptionHandler
  • 作用: 指定处理的异常类型
  • 位置: 异常处理方法上方
  • 参数: 异常类型
  • 示例:
java 复制代码
@ExceptionHandler(ArticleNotFoundException.class)
public ResponseEntity<ErrorResponse> handleArticleNotFound(ArticleNotFoundException e) {
    // 处理 ArticleNotFoundException 异常
}

三、Lombok 注解

3.1 常用注解

@Data
  • 作用: 综合注解,生成多种方法
  • 生成内容:
    • 所有字段的 getter 方法
    • 所有字段的 setter 方法
    • toString() 方法
    • equals()hashCode() 方法
    • RequiredArgsConstructor(必填字段构造方法)
  • 位置: 类上方
  • 示例:
java 复制代码
@Data
public class Article {
    private Long id;
    private String title;
    // 自动生成所有 getter/setter
}
@Getter / @Setter
  • 作用: 只生成 getter 或 setter
  • 位置: 类或字段上方
  • 示例:
java 复制代码
@Getter
@Setter
public class Article {
    private Long id;  // 只生成 getter 和 setter
}
@NoArgsConstructor
  • 作用: 生成无参构造方法
  • 位置: 类上方
  • 示例:
java 复制代码
@NoArgsConstructor
public class Article {
    // 生成 public Article() {}
}
@AllArgsConstructor
  • 作用: 生成全参构造方法
  • 位置: 类上方
  • 示例:
java 复制代码
@AllArgsConstructor
public class Article {
    private Long id;
    private String title;
    // 生成 public Article(Long id, String title) {}
}
@Builder
  • 作用: 建造者模式
  • 位置: 类上方
  • 示例:
java 复制代码
@Builder
public class Article {
    private Long id;
    private String title;
}

// 使用方式
Article article = Article.builder()
    .id(1L)
    .title("标题")
    .build();
@Slf4j
  • 作用: 自动生成日志对象
  • 位置: 类上方
  • 示例:
java 复制代码
@Slf4j
public class ArticleService {
    public void addArticle() {
        log.info("新增文章");
    }
}

四、Spring Data JPA

4.1 Repository 接口

JpaRepository
  • 作用: 继承后自动拥有基本 CRUD 方法
  • 泛型参数:
    • 第一个:实体类型
    • 第二个:主键类型
  • 示例:
java 复制代码
public interface ArticleRepository extends JpaRepository<Article, Long> {
    // 自动拥有 save、findById、findAll、delete 等方法
}
常用方法
方法 作用 返回类型
save(entity) 保存/更新实体 实体对象
findById(id) 按 ID 查询 Optional<Entity>
findAll() 查询全部 List<Entity>
delete(entity) 删除实体 void
deleteById(id) 按 ID 删除 void
count() 统计数量 long
existsById(id) 判断是否存在 boolean

4.2 分页查询

PageRequest
  • 作用: 构建分页请求对象
  • 参数:
    • page - 页码(从 0 开始)
    • size - 每页大小
    • sort - 排序(可选)
  • 示例:
java 复制代码
PageRequest pageRequest = PageRequest.of(0, 10);
Page<Article> page = articleRepository.findAll(pageRequest);
Sort
  • 作用: 构建排序对象
  • 示例:
java 复制代码
Sort sort = Sort.by("createTime").descending();
PageRequest pageRequest = PageRequest.of(0, 10, sort);
Page 对象属性
属性 说明
content 当前页数据列表
totalElements 总记录数
totalPages 总页数
size 每页大小
number 当前页码(从 0 开始)
first 是否第一页
last 是否最后一页

4.3 自定义查询方法

方法命名规则
  • Spring Data JPA 会根据方法名自动生成查询
  • 关键字: findByreadByqueryBycountBygetBy
  • 条件关键字: AndOrBetweenLessThanGreaterThanLikeInOrderBy
示例
java 复制代码
public interface ArticleRepository extends JpaRepository<Article, Long> {
    
    // 按作者查询
    List<Article> findByAuthor(String author);
    
    // 按分类查询
    List<Article> findByCategory(String category);
    
    // 按状态查询
    List<Article> findByStatus(String status);
    
    // 按标题模糊查询
    List<Article> findByTitleContaining(String keyword);
    
    // 多条件查询
    List<Article> findByAuthorAndStatus(String author, String status);
    
    // 排序查询
    List<Article> findByAuthorOrderByCreateTimeDesc(String author);
    
    // 统计数量
    long countByStatus(String status);
}

五、响应对象

5.1 ResponseEntity

作用
  • 可以自定义 HTTP 响应
  • 包含:状态码、响应头、响应体
创建方式
java 复制代码
// 返回 200 成功
ResponseEntity.ok(body);

// 返回 404 未找到
ResponseEntity.status(HttpStatus.NOT_FOUND).body(error);

// 返回 500 错误
ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error);

// 自定义状态码
ResponseEntity.status(400).body(error);
HTTP 状态码枚举
枚举值 状态码 说明
HttpStatus.OK 200 成功
HttpStatus.CREATED 201 创建成功
HttpStatus.BAD_REQUEST 400 参数错误
HttpStatus.NOT_FOUND 404 未找到
HttpStatus.INTERNAL_SERVER_ERROR 500 服务器错误

六、DTO(数据传输对象)

6.1 DTO 的作用

  • 分离关注点: 接口层和实体层解耦
  • 安全性: 避免直接暴露实体类
  • 灵活性: 可以自定义返回字段
  • 可扩展性: 可以添加额外字段或逻辑

6.2 DTO 类型

类型 作用 示例
Request DTO 接收请求参数 ArticleAddRequest
Response DTO 返回响应数据 ArticleResponse

6.3 DTO 与 Entity 转换

手动转换
java 复制代码
private ArticleResponse convertToResponse(Article article) {
    ArticleResponse response = new ArticleResponse();
    response.setId(article.getId());
    response.setTitle(article.getTitle());
    response.setContent(article.getContent());
    // ... 其他字段
    return response;
}

七、Java Stream API

7.1 常用操作

map
  • 作用: 映射转换
  • 示例:
java 复制代码
List<ArticleResponse> responses = articles.stream()
    .map(this::convertToResponse)
    .collect(Collectors.toList());
filter
  • 作用: 过滤
  • 示例:
java 复制代码
List<Article> publishedArticles = articles.stream()
    .filter(article -> "PUBLISHED".equals(article.getStatus()))
    .collect(Collectors.toList());
collect
  • 作用: 收集结果
  • 常用收集器:
    • Collectors.toList() - 收集为 List
    • Collectors.toSet() - 收集为 Set
    • Collectors.toMap() - 收集为 Map

八、Optional 类

8.1 作用

  • 避免 NullPointerException
  • 更优雅的空值处理

8.2 常用方法

orElse
  • 作用: 如果值为空,返回默认值
  • 示例:
java 复制代码
Article article = articleRepository.findById(id)
    .orElse(new Article());  // 如果找不到,返回新对象
orElseThrow
  • 作用: 如果值为空,抛出异常
  • 示例:
java 复制代码
Article article = articleRepository.findById(id)
    .orElseThrow(() -> new ArticleNotFoundException(id));
isPresent
  • 作用: 判断是否有值
  • 示例:
java 复制代码
Optional<Article> optional = articleRepository.findById(id);
if (optional.isPresent()) {
    Article article = optional.get();
}

九、数据库配置

9.1 H2 数据库

内存模式
  • 配置: jdbc:h2:mem:testdb
  • 特点: 数据存储在内存中,重启后清空
  • 适用: 测试、学习
文件模式
  • 配置: jdbc:h2:file:./data
  • 特点: 数据存储在文件中,重启后保留
  • 适用: 开发、演示
H2 控制台
  • 访问: http://localhost:8080/h2-console
  • JDBC URL: jdbc:h2:file:./data
  • 用户名: sa
  • 密码:

9.2 JPA 配置

properties 复制代码
# 显示 SQL 语句
spring.jpa.show-sql=true

# 自动创建/更新表结构
spring.jpa.hibernate.ddl-auto=update

# 可选值:
# - none: 不做任何操作
# - validate: 验证表结构
# - update: 自动更新表结构
# - create: 每次启动创建新表(删除旧数据)
# - create-drop: 启动创建,关闭删除

十、常见问题解决

10.1 Lombok 不生效

问题:

makefile 复制代码
java: java.lang.ExceptionInInitializerError

原因: Lombok 版本与 Java 版本不兼容

解决: 升级 Lombok 到最新版本

xml 复制代码
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.38</version>
</dependency>

10.2 警告信息忽略

以下警告不影响功能,可以忽略:

  1. H2 数据库警告:
lua 复制代码
Thread starvation or clock leap detected
  1. Tomcat 本地方法警告:
sql 复制代码
WARNING: A restricted method in java.lang.System has been called

十一、最佳实践

11.1 分层原则

  • Controller: 只处理 HTTP 相关逻辑,不写业务代码
  • Service: 处理业务逻辑、数据转换、异常处理
  • Repository: 只负责数据库操作

11.2 DTO 使用原则

  • 所有接口都使用 DTO,不直接返回 Entity
  • Request DTO 和 Response DTO 分离
  • 复杂转换逻辑封装为私有方法

11.3 异常处理原则

  • 业务异常:自定义异常类
  • 全局异常:使用 @RestControllerAdvice
  • 统一响应格式:ErrorResponse

11.4 事务管理原则

  • Service 类添加 @Transactional
  • 查询方法可以不加事务
  • 写操作必须加事务

十二、扩展学习方向

12.1 下一步学习

  • 参数校验: 使用 @Valid@Validated
  • 统一响应: Result/Response 包装类
  • 日志记录: Slf4j + Logback
  • 接口文档: Swagger/Knife4j
  • 单元测试: JUnit + Mockito
  • 缓存: Spring Cache + Redis
  • 安全: Spring Security + JWT



Spring Boot 第一阶段扩展知识点

学习日期: 2026年7月1日 项目: 文章管理系统 - 基础增强


一、参数校验(Validation)

1.1 常用校验注解

注解 作用 示例
@NotBlank 字符串不能为空(trim后长度>0) @NotBlank(message = "标题不能为空")
@NotNull 值不能为 null @NotNull(message = "ID不能为空")
@NotEmpty 集合/字符串不能为空 @NotEmpty(message = "列表不能为空")
@Size 长度范围限制 @Size(max = 100, message = "不超过100字符")
@Min / @Max 数值范围限制 @Min(value = 1, message = "必须大于0")
@Pattern 正则表达式校验 @Pattern(regexp = "^[A-Z]+$")
@Email 邮箱格式校验 @Email(message = "邮箱格式错误")

1.2 使用方式

1. 在 DTO 上添加注解:

java 复制代码
@Data
public class ArticleAddRequest {
    @NotBlank(message = "标题不能为空")
    @Size(max = 100, message = "标题不能超过100个字符")
    private String title;
}

2. 在 Controller 上启用校验:

java 复制代码
@PostMapping("/add")
public Result<ArticleResponse> addArticle(@Valid @RequestBody ArticleAddRequest request) {
    // @Valid 触发校验
}

1.3 校验异常处理

java 复制代码
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Result<Map<String, String>>> handleValidationException(
        MethodArgumentNotValidException e) {
    Map<String, String> errors = new HashMap<>();
    e.getBindingResult().getAllErrors().forEach(error -> {
        String fieldName = ((FieldError) error).getField();
        String errorMessage = error.getDefaultMessage();
        errors.put(fieldName, errorMessage);
    });
    return ResponseEntity.badRequest().body(Result.error(errors));
}

二、统一响应封装

2.1 为什么需要统一响应?

  • 前端处理逻辑统一
  • 便于错误处理
  • 接口文档规范
  • 便于日志追踪

2.2 Result 类设计

java 复制代码
@Data
public class Result<T> {
    private Integer code;
    private String message;
    private T data;

    public static <T> Result<T> success(T data) { ... }
    public static <T> Result<T> error(Integer code, String message) { ... }
}

2.3 响应格式

json 复制代码
{
    "code": 200,
    "message": "操作成功",
    "data": { ... }
}

三、日志记录

3.1 Slf4j 使用

添加注解:

java 复制代码
@Service
@Slf4j
public class ArticleService {
    // ...
}

日志级别:

java 复制代码
log.trace("最详细的追踪信息");
log.debug("调试信息");
log.info("关键业务操作");
log.warn("警告信息");
log.error("错误信息");

3.2 Logback 配置

配置文件:logback-spring.xml

主要配置项:

  • 控制台输出(彩色)
  • 文件输出(滚动)
  • 错误日志单独存放
  • 日志级别控制

3.3 日志最佳实践

场景 日志级别 示例
方法入口/出口 DEBUG log.debug("查询文章,ID: {}", id)
业务操作成功 INFO log.info("新增文章成功,ID: {}", id)
业务异常 WARN log.warn("文章不存在,ID: {}", id)
系统异常 ERROR log.error("数据库连接失败", e)

四、自定义 JPA 查询

4.1 方法命名规则

Spring Data JPA 根据方法名自动生成查询:

关键字 示例 生成的 SQL
findBy findByTitle WHERE title = ?
Containing findByTitleContaining WHERE title LIKE %?%
And findByAuthorAndStatus WHERE author = ? AND status = ?
Or findByAuthorOrStatus WHERE author = ? OR status = ?
Between findByCreateTimeBetween WHERE create_time BETWEEN ? AND ?
OrderBy findByStatusOrderByCreateTimeDesc ORDER BY create_time DESC

4.2 常用查询示例

java 复制代码
// 精确查询
List<Article> findByAuthor(String author);

// 模糊查询
List<Article> findByTitleContaining(String keyword);

// 组合查询
List<Article> findByAuthorAndStatus(String author, String status);

// 范围查询
List<Article> findByCreateTimeBetween(LocalDateTime start, LocalDateTime end);

// 排序查询
List<Article> findByStatusOrderByCreateTimeDesc(String status);

// 统计
long countByStatus(String status);

// 存在判断
boolean existsByTitle(String title);

五、单元测试

5.1 测试注解

注解 作用
@Test 标记测试方法
@DisplayName 测试显示名称
@BeforeEach 每个测试前执行
@AfterEach 每个测试后执行
@Mock 创建模拟对象
@InjectMocks 注入模拟对象

5.2 Mockito 常用方法

java 复制代码
// 模拟返回值
when(repository.findById(1L)).thenReturn(Optional.of(article));

// 模拟 void 方法
doNothing().when(repository).delete(any());

// 验证调用次数
verify(repository, times(1)).save(any());

// 验证从未调用
verify(repository, never()).delete(any());

5.3 测试命名规范

java 复制代码
@Test
@DisplayName("方法名_场景_期望结果")
void methodName_scenario_expectedResult() {
    // given - 准备数据

    // when - 执行测试

    // then - 验证结果
}
相关推荐
lichenyang4531 小时前
从一个按钮开始,理解 ASCF 框架到底在做什么
前端
古夕2 小时前
第三方 SSO 接入实践:redirect_uri 编码、回调一致性与跨项目联调
前端·vue.js
朦胧之2 小时前
页面白屏卡住排查方法
前端·javascript
用户593608741402 小时前
Playwright 黑魔法:用 ClipboardEvent 绕过 React 富文本编辑器
前端
石山岭2 小时前
自己动手写了一个 Android 虚拟定位 App:GPSSimulate 技术实
android·前端
犇驫聊AI3 小时前
Chrome DevTools MCP + Claude Code 自定义skills生成接口代码生成器
前端·javascript
kyriewen3 小时前
别再这样写 async/await 了:我在 Code Review 中见过最多的 8 个错误
前端·javascript·面试
hoLzwEge3 小时前
node-linker VS shamefully-hoist
前端·前端框架
袋鱼不重3 小时前
解决 Web 端图片预览与下载颜色不一致的一种工程方案
前端·后端