SKILL.md
唯讀
名稱
spring-boot-engineer
描述
生成 Spring Boot 3.x 設定檔、建立 REST 控制器、實作 Spring Security 6 驗證流程、設定 Spring Data JPA 儲存庫,以及配置響應式 WebFlux 端點。適用於建置 Spring Boot 3.x 應用程式、微服務或響應式 Java 應用程式;在需要 Spring Data JPA、Spring Security 6、WebFlux、Spring Cloud 整合、Java REST API 設計或微服務 Java 架構時呼叫。
Spring Boot 工程師
核心工作流程
- 分析需求 — 確認服務邊界、API、資料模型與安全需求
- 設計架構 — 規劃微服務、資料存取、雲端整合及安全性;在撰寫程式碼前先確認設計方案
- 實作功能 — 使用建構子注入(constructor injection)與分層架構建立服務(參見下方「快速入門」)
- 強化安全性 — 加入 Spring Security、OAuth2、方法級安全性及 CORS 設定;驗證安全規則可順利編譯並通過測試。若編譯或測試失敗:檢視錯誤輸出,修正失效的規則或設定,並在重新執行通過後再繼續
- 執行測試 — 撰寫單元測試、整合測試與切片測試;執行
./mvnw test(或./gradlew test)並確認全部通過後再繼續。若測試失敗:檢視堆疊追蹤(stack trace),定位出問題的斷言或元件,修復問題後重新執行完整測試套件 - 部署應用 — 透過 Actuator 設定健康檢查與可觀測性;驗證
/actuator/health回傳UP。若狀態為DOWN:檢查回應中的components詳細資訊,解決故障元件(例如資料源、訊息代理 broker),並重新驗證
參考指南
根據情境載入詳細指引:
| 主題 | 參考文件 | 載入時機 |
|---|---|---|
| Web 層 | references/web.md |
控制器、REST API、驗證(Validation)、例外處理 |
| 資料存取 | references/data.md |
Spring Data JPA、儲存庫(Repositories)、交易(Transactions)、投影(Projections) |
| 安全性 | references/security.md |
Spring Security 6、OAuth2、JWT、方法級安全性 |
| 雲原生 | references/cloud.md |
Spring Cloud、Config、Discovery、Gateway、彈性恢復力(Resilience) |
| 測試 | references/testing.md |
@SpringBootTest、MockMvc、Testcontainers、測試切片 |
快速入門 — 最小可執行結構
標準的 Spring Boot 功能包含以下層級,可直接作為複製貼上的起點。
Entity
@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;
// getter / setter 或使用 @Data (Lombok)
}
Repository
public interface ProductRepository extends JpaRepository<Product, Long> {
List<Product> findByNameContainingIgnoreCase(String name);
}
Service (建構子注入)
@Service
public class ProductService {
private final ProductRepository repo;
public ProductService(ProductRepository repo) { // 建構子注入 — 不使用 @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 Controller
@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
) {}
全域例外處理器 (Global Exception Handler)
@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());
}
}
測試切片 (Test Slice)
@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"));
}
}
規範
必須遵循 (MUST DO)
| 規則 | 正確模式 |
|---|---|
| 建構子注入 | public MyService(Dep dep) { this.dep = dep; } |
| 驗證 API 輸入 | 在所有變更資料的端點加上 @Valid @RequestBody MyRequest req |
| 型別安全設定 | 使用 @ConfigurationProperties(prefix = "app") 綁定至 record 或 class |
| 恰當使用 Stereotype 註解 | 商業邏輯用 @Service,資料存取用 @Repository,HTTP 端點用 @RestController |
| 交易範圍 (Transaction Scope) | 多步驟寫入操作加上 @Transactional;讀取操作加上 @Transactional(readOnly = true) |
| 隱藏內部細節 | 在 @RestControllerAdvice 中捕捉領域例外;回傳 Problem Details,而非堆疊追蹤 |
| 外部化機密資訊 | 使用環境變數或 Spring Cloud Config — 絕不硬編碼在 application.properties |
嚴禁事項 (MUST NOT DO)
- 使用欄位注入(在欄位上加
@Autowired) - 忽略 API 端點的輸入驗證
- 在適用
@Service/@Repository/@Controller時誤用@Component - 混合阻塞式與響應式程式碼(例如在 WebFlux 鏈中呼叫
.block()) - 將機密或憑證儲存在
application.properties/application.yml中 - 硬編碼 URL、憑證或特定環境的值
- 使用已廢棄的 Spring Boot 2.x 模式(例如
WebSecurityConfigurerAdapter)




