My Retro App项目开发指南
项目初始化与依赖配置
Spring Boot基础配置
在第二章中,我们完成了My Retro App的基础配置,当时仅包含部分属性配置用于演示Spring Boot特性。本节将完善项目结构,添加必要的依赖项、业务类以及完整的Web功能(包括REST API接口)。
项目初始化采用Gradle构建工具,以下是完整的build.gradle
配置文件:
plugins {id 'java'id 'org.springframework.boot' version '3.2.3'id 'io.spring.dependency-management' version '1.1.4'
}group = 'com.apress'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'repositories {mavenCentral()maven { url 'https://repo.spring.io/milestone' }maven { url 'https://repo.spring.io/snapshot' }
}dependencies {implementation 'org.springframework.boot:spring-boot-starter-web'implementation 'org.springframework.boot:spring-boot-starter-validation'implementation 'org.springframework.boot:spring-boot-starter-aop'// LombokcompileOnly 'org.projectlombok:lombok'annotationProcessor 'org.projectlombok:lombok'// 配置处理annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"// Web资源implementation 'org.webjars:bootstrap:5.2.3'// 测试testImplementation 'org.springframework.boot:spring-boot-starter-test'
}tasks.named('test') {useJUnitPlatform()
}test {testLogging {events "passed", "skipped", "failed"showExceptions trueexceptionFormat "full"showCauses trueshowStackTraces trueshowStandardStreams = false}
}
关键依赖说明
Web功能支持
spring-boot-starter-web
是核心依赖,包含:
- Spring Web和WebMVC模块
- 内嵌Tomcat服务器
- Jackson JSON处理库
- 自动配置Web注解(如
@RestController
、@GetMapping
等)
数据校验
spring-boot-starter-validation
提供Jakarta Validation实现,支持通过注解(如@NotNull
、@NotBlank
)对领域对象(RetroBoard和Card类)进行校验。
AOP支持
spring-boot-starter-aop
实现面向切面编程,用于:
- 解耦横切关注点
- 减少代码重复
- 增强代码可读性
开发效率工具
Lombok库通过注解自动生成:
- Getter/Setter方法
toString()
方法- 构造器
- Builder模式实现
自动配置机制
Spring Boot启动时会自动:
- 扫描
build.gradle
中的所有依赖 - 根据依赖自动配置相关组件
- 完成Bean的装配和初始化
- 准备完整的Web应用环境
这种"约定优于配置"的机制显著减少了样板代码,开发者只需声明依赖即可获得完整功能支持。
项目结构演进
初始目录结构仅包含基础配置类:
src/
├── main/
│ ├── java/
│ │ └── com/apress/myretro/
│ │ ├── MyRetroApplication.java
│ │ └── config/
│ └── resources/
完善后的结构包含完整业务模块:
src/
├── main/
│ ├── java/
│ │ └── com/apress/myretro/
│ │ ├── advice/ # AOP切面
│ │ ├── board/ # 领域模型
│ │ ├── config/ # 配置类
│ │ ├── exception/ # 异常处理
│ │ ├── persistence/ # 数据持久化
│ │ ├── service/ # 业务服务
│ │ └── web/ # Web控制器
│ └── resources/
这种模块化结构使代码职责清晰,便于维护和扩展。每个包对应明确的业务功能,后续章节将详细介绍各模块实现。
领域模型设计与实现
RetroBoard核心领域类
RetroBoard类作为看板应用的核心领域模型,采用Lombok注解简化代码结构:
@Builder
@Data
public class RetroBoard {private UUID id;@NotNull@NotBlank(message = "必须提供看板名称")private String name;@Singularprivate List cards;
}
关键设计要点:
- Builder模式:通过
@Builder
实现流畅API创建对象实例 - 数据校验:
@NotNull
确保字段非空@NotBlank
附加业务提示信息
- 集合处理:
@Singular
注解支持逐个添加卡片元素,最终生成不可变列表
Card领域类实现
卡片实体通过组合方式与看板建立关联:
@Builder
@Data
public class Card {private UUID id;@NotBlank(message = "必须填写评论内容")@NotNullprivate String comment;@NotNull(message = "必须指定卡片类型:HAPPY|MEH|SAD")private CardType cardType;
}
验证规则设计:
- 评论内容强制非空且非空白字符串
- 卡片类型通过枚举限定取值范围
- 错误消息采用业务语言描述
CardType枚举设计
枚举类明确定义三种卡片状态:
public enum CardType {HAPPY, // 积极反馈MEH, // 中立意见 SAD // 负面反馈
}
业务意义:
- HAPPY:表示会议中的积极事项
- MEH:需要改进的中性意见
- SAD:需要重点解决的问题
验证框架实践
Jakarta Validation的应用特点:
- 级联验证:通过
@Valid
触发嵌套对象验证 - 错误处理:
@ExceptionHandler(MethodArgumentNotValidException.class)
public Map handleValidationExceptions(...) {// 提取字段级错误详情ex.getBindingResult().getAllErrors().forEach(error -> {String fieldName = ((FieldError) error).getField();String message = error.getDefaultMessage();errors.put(fieldName, message);});
}
- 校验时机:在Controller方法参数绑定阶段自动触发
Builder模式增强
Lombok生成的Builder方法使用示例:
RetroBoard.builder().id(UUID.randomUUID()).name("项目回顾会议").card(Card.builder().comment("进度超前").cardType(