Spring Boot 3 Modern Rules
Boot 3+ defaults: starters, configuration properties, profiles, and structured logging.
# CLAUDE.md — Spring Boot 3 Modern Rules
## Version baseline
- Spring Boot 3.2+ (3.4 if you can adopt). Java 21.
- Migrate `javax.*` → `jakarta.*` once and for all. Boot 3 dropped `javax`.
- Pin the Spring Boot parent in `pom.xml` / `plugins { id 'org.springframework.boot' version '...' }`. Don't manually align Spring deps.
## Project layout
```
src/main/java/com/app/
Application.java # @SpringBootApplication
config/
domain/
api/ # controllers
service/
repository/
Application.java
src/main/resources/
application.yml # default config
application-dev.yml # profile-specific overrides
application-prod.yml
```
- Avoid splitting "common" beans across many modules. Boot's autoconfig discovers what's on the classpath.
## Configuration properties
- `@ConfigurationProperties` over `@Value`. Use records:
```java
@ConfigurationProperties("app.email")
record EmailProperties(String fromAddress, String smtpHost, int smtpPort) {}
```
- `@EnableConfigurationProperties(EmailProperties.class)` once on a `@Configuration` class.
- Validate with `@Validated` + `@NotNull` / `@NotEmpty` on fields. Boot fails fast on bad config.
## Profiles
- `dev`, `test`, `prod`. Activate with `SPRING_PROFILES_ACTIVE=prod` (env var) or `--spring.profiles.active=prod`.
- Don't have profile-specific Java code (`if (env.equals("dev"))`). Use `@Profile` on beans.
- `application-{profile}.yml` overrides `application.yml`. Keep secrets out — use env vars or a secret manager.
## Logging
- Default to **Logback** (Boot's default). Use **structured JSON** (logstash-encoder) in production.
- `LOG_LEVEL_app=DEBUG` env var overrides at runtime (Boot reads logging.level.* env vars).
- One logger per class: `private static final Logger log = LoggerFactory.getLogger(MyService.class);`.
- Don't log sensitive data (PII, tokens). Add a redaction filter if there's any risk.
## Auto-configuration
- Boot configures DataSource, JPA, Web, Security, etc. based on what's on the classpath.
- Override defaults with explicit beans — they win over auto-config.
- Disable specific auto-config: `@SpringBootApplication(exclude = SecurityAutoConfiguration.class)` only when you have a real reason.
## Starters
- `spring-boot-starter-web` for Servlet stack, `spring-boot-starter-webflux` for reactive. Pick one.
- `spring-boot-starter-data-jpa` brings Hibernate + Spring Data JPA + a connection pool.
- `spring-boot-starter-actuator` for ops endpoints. Always include in production.
## Health & lifecycle
- Boot's `/actuator/health` endpoint is on by default. Add component-specific checks via `HealthIndicator`.
- Configure `management.endpoint.health.probes.enabled=true` for K8s liveness/readiness split.
- Graceful shutdown: `server.shutdown=graceful`, `spring.lifecycle.timeout-per-shutdown-phase=30s`. Drain in-flight requests on SIGTERM.
## Don't
- Don't `application.yml` your way to a 500-line config. Split by profile or extract to `@ConfigurationProperties`.
- Don't disable Spring's exception handling to "see the real error". Use a `@ControllerAdvice` instead.
- Don't run with `spring.jpa.hibernate.ddl-auto=update` in production. Use Flyway or Liquibase.
- Don't put `@Bean` methods in your `Application.java`. Move to a dedicated `@Configuration` class.
Other Spring templates
Spring Framework Core Rules
Dependency injection, bean lifecycle, configuration classes, and profiles.
Spring Data JPA
Repositories, derived queries, custom JPQL, projections, and N+1 prevention.
Spring Security Rules
SecurityFilterChain (no WebSecurityConfigurerAdapter), OAuth2 resource server, JWT.
Spring MVC Rules
Controllers, ResponseEntity, validation, exception handling, and content negotiation.
Spring WebFlux (Reactive)
Reactive Spring with Mono/Flux, R2DBC, backpressure, and non-blocking patterns.