SpringBoot模式
Mattakushi4322026-10-26查看 925复制 455
何时激活:Spring Boot、@RestController、@Service、@Repository、自动配置、配置文件、执行器、异常处理、Spring MVC
📘如何使用这个技能
- 1复制技能内容·点击上方「Copy SKILL.md」复制全部内容,或 Download 下载到本地
- 2打开你的 AI 客户端·支持 Claude Code、Trae、Cursor、ChatGPT、DeepSeek、Kimi 等任意 AI 助手
- 3粘贴为系统提示/知识文件·Claude Code:放入 .claude/skills/ 目录;普通对话:作为首条消息发送并说「请严格按这份技能文档执行」
- 4直接提出你的需求·AI 会按技能定义的工作流、格式和约束来处理,无需再解释背景
💡 提示:技能生效后,每次对话只需一句需求,AI 会按 SKILL.md 的流程执行。
SKILL.md5185 chars
---
name: springboot-patterns
description: "When to activate: Spring Boot, @RestController, @Service, @Repository, auto-configuration, profiles, actuator, exception handling, Spring MVC"
origin: zakr
metadata:
namespace: zakr/devtools-pack
version: 1.0.0
category: engineering
language: java-kotlin
platforms: [claude-code, codex, gemini-cli, cursor, aider, windsurf]
---
# Spring Boot 3 Patterns
## Controller Layer
```java
@RestController
@RequestMapping("/api/v1/users")
@RequiredArgsConstructor
public class UserController {
private final UserService userService;
@GetMapping("/{id}")
public ResponseEntity<UserResponse> getUser(@PathVariable Long id) {
return ResponseEntity.ok(userService.findById(id));
}
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public UserResponse createUser(@Valid @RequestBody CreateUserRequest request) {
return userService.create(request);
}
@GetMapping
public Page<UserResponse> listUsers(
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "20") int size) {
return userService.findAll(PageRequest.of(page, size));
}
}
```
## Service Layer
```java
@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;
private final UserMapper userMapper;
public UserResponse findById(Long id) {
return userRepository.findById(id)
.map(userMapper::toResponse)
.orElseThrow(() -> new ResourceNotFoundException("User", id));
}
@Transactional
public UserResponse create(CreateUserRequest request) {
if (userRepository.existsByEmail(request.email())) {
throw new DuplicateResourceException("Email already in use");
}
User user = userMapper.toEntity(request);
return userMapper.toResponse(userRepository.save(user));
}
}
```
## Repository Layer
```java
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
boolean existsByEmail(String email);
Optional<User> findByEmail(String email);
@Query("SELECT u FROM User u WHERE u.status = :status AND u.createdAt > :since")
Page<User> findActiveUsersSince(@Param("status") UserStatus status,
@Param("since") Instant since,
Pageable pageable);
}
```
## Global Exception Handling
```java
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public ProblemDetail handleNotFound(ResourceNotFoundException ex) {
ProblemDetail detail = ProblemDetail.forStatus(HttpStatus.NOT_FOUND);
detail.setTitle("Resource Not Found");
detail.setDetail(ex.getMessage());
return detail;
}
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ProblemDetail handleValidation(MethodArgumentNotValidException ex) {
ProblemDetail detail = ProblemDetail.forStatus(HttpStatus.BAD_REQUEST);
detail.setTitle("Validation Failed");
Map<String, String> errors = new HashMap<>();
ex.getBindingResult().getFieldErrors()
.forEach(e -> errors.put(e.getField(), e.getDefaultMessage()));
detail.setProperty("errors", errors);
return detail;
}
}
```
## Application Properties (YAML)
```yaml
spring:
application:
name: my-service
datasource:
url: jdbc:postgresql://localhost:5432/mydb
username: ${DB_USER}
password: ${DB_PASS}
jpa:
hibernate:
ddl-auto: validate
show-sql: false
properties:
hibernate.default_batch_fetch_size: 20
management:
endpoints:
web:
exposure:
include: health,info,metrics,prometheus
endpoint:
health:
show-details: when_authorized
```
## Profiles
```java
@Configuration
@Profile("prod")
public class ProdConfig {
@Bean
public CacheManager cacheManager() {
return new RedisCacheManager(...);
}
}
// application-dev.yml — local H2
// application-prod.yml — real Postgres + Redis
```
## Actuator Custom Health Indicator
```java
@Component
public class DatabaseHealthIndicator implements HealthIndicator {
private final DataSource dataSource;
@Override
public Health health() {
try (Connection conn = dataSource.getConnection()) {
conn.prepareStatement("SELECT 1").execute();
return Health.up().build();
} catch (SQLException ex) {
return Health.down(ex).build();
}
}
}
```
## Key Rules
- Use `@Transactional(readOnly = true)` on service class, override with `@Transactional` on write methods
- Return `ResponseEntity` only when you need to set headers/status dynamically; use `@ResponseStatus` otherwise
- Validate DTOs with `@Valid`; use `record` types for immutable request/response objects
- Use `ProblemDetail` (RFC 7807) for error responses — Spring Boot 3 native support
- Externalize all secrets via `${ENV_VAR}` — never hardcode credentials