关于 spring-boot-engineer
面向构建生产级 Java 服务的 Spring Boot 工程技能,涵盖架构设计、实现、安全、测试与部署,并提供专题参考和起步代码结构。
主要功能
- 01需求与架构规划
- 02分层 Spring Boot 实现指导
- 03安全与输入验证实践
- 04单元、集成及切片测试
- 05Actuator 健康检查指导
适用场景
- 01规划 REST 服务边界与 API
- 02实现经过验证的 Spring Boot 端点
- 03排查测试或安全规则失败
- 04部署前检查服务健康状态
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ jeffallan/ claude-skills --skill spring-boot-engineer安装后在 Claude Code 中输入/spring-boot-engineer确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/cloud.mddata.mdsecurity.mdtesting.mdweb.md详细介绍
Spring Boot 工程师
核心工作流
- 分析需求 — 确定服务边界、API、数据模型和安全需求
- 设计架构 — 规划微服务、数据访问、云集成和安全;编码前确认设计
- 实施 — 使用构造函数注入和分层架构创建服务(参见下方的快速入门)
- 保障安全 — 添加 Spring Security、OAuth2、方法安全和 CORS 配置;确认安全规则能够编译并通过测试。如果编译或测试失败:检查错误输出,修复失败的规则或配置,然后重新运行再继续
- 测试 — 编写单元、集成和切片测试;运行
./mvnw test(或./gradlew test),并确认全部通过后再继续。如果测试失败:检查堆栈跟踪,定位失败的断言或组件,修复问题,然后重新运行完整测试套件 - 部署 — 通过 Actuator 配置健康检查和可观测性;验证
/actuator/health返回UP。如果健康状态为DOWN:检查响应中的components详情,解决故障组件(例如数据源、消息代理),然后重新验证
参考指南
根据上下文加载详细指南:
| 主题 | 参考资料 | 加载时机 |
|---|---|---|
| Web 层 | references/web.md | 控制器、REST API、验证、异常处理 |
| 数据访问 | references/data.md | Spring Data JPA、仓库、事务、投影 |
| 安全 | references/security.md | Spring Security 6、OAuth2、JWT、方法安全 |
| 云原生 | references/cloud.md | Spring Cloud、Config、Discovery、Gateway、弹性 |
| 测试 | references/testing.md | @SpringBootTest、MockMvc、Testcontainers、测试切片 |
快速入门 — 最小可用结构
标准的 Spring Boot 功能由以下层组成。可将这些示例用作复制粘贴的起点。
实体
@Entity
@Table(name = "products")
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotBlank
private String name;
@DecimalMin("0.0")
private BigDecimal price;
// getters / setters or use @Data (Lombok)
}
仓库
public interface ProductRepository extends JpaRepository<Product, Long> {
List<Product> findByNameContainingIgnoreCase(String name);
}
服务(构造函数注入)
@Service
public class ProductService {
private final ProductRepository repo;
public ProductService(ProductRepository repo) { // constructor injection — no @Autowired
this.repo = repo;
}
@Transactional(readOnly = true)
public List<Product> search(String name) {
return repo.findByNameContainingIgnoreCase(name);
}
@Transactional
public Product create(ProductRequest request) {
var product = new Product();
product.setName(request.name());
product.setPrice(request.price());
return repo.save(product);
}
}
REST 控制器
@RestController
@RequestMapping("/api/v1/products")
@Validated
public class ProductController {
private final ProductService service;
public ProductController(ProductService service) {
this.service = service;
}
@GetMapping
public List<Product> search(@RequestParam(defaultValue = "") String name) {
return service.search(name);
}
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public Product create(@Valid @RequestBody ProductRequest request) {
return service.create(request);
}
}
DTO(record)
public record ProductRequest(
@NotBlank String name,
@DecimalMin("0.0") BigDecimal price
) {}
全局异常处理器
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Map<String, String> handleValidation(MethodArgumentNotValidException ex) {
return ex.getBindingResult().getFieldErrors().stream()
.collect(Collectors.toMap(FieldError::getField, FieldError::getDefaultMessage));
}
@ExceptionHandler(EntityNotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public Map<String, String> handleNotFound(EntityNotFoundException ex) {
return Map.of("error", ex.getMessage());
}
}
测试切片
@WebMvcTest(ProductController.class)
class ProductControllerTest {
@Autowired MockMvc mockMvc;
@MockBean ProductService service;
@Test
void createProduct_validRequest_returns201() throws Exception {
var product = new Product(); product.setName("Widget"); product.setPrice(BigDecimal.TEN);
when(service.create(any())).thenReturn(product);
mockMvc.perform(post("/api/v1/products")
.contentType(MediaType.APPLICATION_JSON)
.content("""{"name":"Widget","price":10.0}"""))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.name").value("Widget"));
}
}
约束
必须执行
| 规则 | 正确模式 |
|---|---|
| 构造函数注入 | public MyService(Dep dep) { this.dep = dep; } |
| 验证 API 输入 | 在每个有修改操作的端点上使用 @Valid @RequestBody MyRequest req |
| 类型安全的配置 | 将 @ConfigurationProperties(prefix = "app") 绑定到 record/class |
| 使用合适的构造型注解 | 业务逻辑使用 @Service,数据访问使用 @Repository,HTTP 使用 @RestController |
| 事务范围 | 多步写入使用 @Transactional;读取操作使用 @Transactional(readOnly = true) |
| 隐藏内部细节 | 在 @RestControllerAdvice 中捕获领域异常;返回问题详情,而非堆栈跟踪 |
| 将密钥外置 | 使用环境变量或 Spring Cloud Config;绝不放在 application.properties 中 |
不得执行
- 使用字段注入(在字段上使用
@Autowired) - 跳过 API 端点的输入验证
- 在适用
@Service/@Repository/@Controller时使用@Component - 混用阻塞式和响应式代码(例如,在 WebFlux 链中调用
.block()) - 将密钥或凭据存储在
application.properties/application.yml中 - 硬编码 URL、凭据或特定环境的值
- 使用已弃用的 Spring Boot 2.x 模式(例如
WebSecurityConfigurerAdapter)
由 @jeffallan 维护;他是 Synergetic Solutions 的首席顾问。
评论
支持 Markdown