Skip to main content

spring-boot-engineer

Use when building, modifying, or reviewing Spring Boot 4.x applications (Spring Framework 7, Spring Security 7, Hibernate 7, Jackson 3) in Java or Kotlin — REST controllers, Spring Data JPA repositories, OAuth2 / JWT, WebFlux reactive endpoints, Kafka / event-driven code, Resilience4j, Spring Cloud, or Spring Boot tests. Covers common pitfalls that break in production: @Transactional self-invocation, N+1 queries, Kotlin + JPA plugins, blocking calls inside WebFlux. Migrating from Boot 3.x? See Setup Check — major breaking changes: Jackson 3 package rename, @MockBean removed, and() in Security DSL removed, Undertow dropped.

Informations de source

Dépôt
JetBrains/junie-extensions
Dernière activité de la source
27 avril 2026 à 08:24
Langue détectée de SKILL.md
anglais
Étoiles
23
Forks
6

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Explorateur de fichiers
12 fichiers

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
name
spring-boot-engineer
description
Use when building, modifying, or reviewing Spring Boot 4.x applications (Spring Framework 7, Spring Security 7, Hibernate 7, Jackson 3) in Java or Kotlin — REST controllers, Spring Data JPA repositories, OAuth2 / JWT, WebFlux reactive endpoints, Kafka / event-driven code, Resilience4j, Spring Cloud, or Spring Boot tests. Covers common pitfalls that break in production: @Transactional self-invocation, N+1 queries, Kotlin + JPA plugins, blocking calls inside WebFlux. Migrating from Boot 3.x? See Setup Check — major breaking changes: Jackson 3 package rename, @MockBean removed, and() in Security DSL removed, Undertow dropped.
# Spring Boot Engineer ## Core Workflow 1. **Setup check** — run Setup Check below before writing any code. 2. **Design first** — for non-trivial work, confirm service boundaries, data model, security needs, and reactive-vs-servlet choice before coding. 3. **Implement bottom-up** — entity → repository → service → controller. Constructor injection only. Write DTOs as records (Java) or `data class` (Kotlin), never expose JPA entities from the web layer. 4. **Secure** — `@PreAuthorize` / `SecurityFilterChain`, externalize secrets, validate all input with `@Valid`. 5. **Test** — slice tests (`@WebMvcTest`, `@DataJpaTest`) for fast feedback, one `@SpringBootTest` per critical flow, Testcontainers for anything that touches a real DB. 6. **Verify** — run `./mvnw test` or `./gradlew test` and confirm `/actuator/health` returns `UP` before declaring done. ## Setup Check **Mandatory before any code change.** ### Step 1 — Is this actually a Spring Boot project? Look for one of these, in this order: - `spring-boot-starter-parent` or `spring-boot-dependencies` in `pom.xml`. - `org.springframework.boot` plugin in `build.gradle` / `build.gradle.kts`. - A class annotated with `@SpringBootApplication`. If none → stop and tell the user this isn't a Spring Boot project before proceeding. ### Step 2 — Kotlin project? Verify required compiler plugins. If `src/main/kotlin/` exists **and** Spring / JPA is used, both plugins below must be configured. Without them Spring proxies and JPA entities fail at runtime with cryptic errors: | Plugin | Why it's needed | |---|---| | `kotlin("plugin.spring")` (`kotlin-spring`) | Opens classes annotated with `@Component` / `@Service` / `@Configuration` / `@Transactional` / `@Async` / `@Cacheable` / `@SpringBootTest` — CGLIB proxies cannot subclass `final` classes. | | `kotlin("plugin.jpa")` (`kotlin-jpa`) | Generates a no-arg constructor for `@Entity` / `@Embeddable` / `@MappedSuperclass`. Required for JPA to instantiate entities via reflection. | If either is missing → **suggest adding it** before implementing anything that relies on it. ```kotlin plugins { kotlin("plugin.spring") version "<kotlin-version>" kotlin("plugin.jpa") version "<kotlin-version>" } ``` Also confirm `kotlin-reflect` is on the classpath (included by `spring-boot-starter`). ### Step 3 — Java version & runtime Spring Boot 4.x requires **Java 17+** (Java 21+ recommended — first-class virtual thread support). Check `<java.version>` (Maven) or `java.toolchain` / `sourceCompatibility` (Gradle). Virtual threads: enable via `spring.threads.virtual.enabled=true`. Don't use them unconditionally — harmful with `synchronized` blocks and `ThreadLocal`-heavy libraries. **Undertow is no longer supported** in Boot 4 (dropped Servlet 6.1 compatibility). Use Tomcat (default) or Jetty. ### Step 4 — Jackson version Spring Boot 4 defaults to **Jackson 3**. Most packages were renamed: `com.fasterxml.jackson` → `tools.jackson`. Exception: `jackson-annotations` intentionally keeps the old namespace (`com.fasterxml.jackson.annotation`) for backward compatibility. Any code importing `jackson-databind` or `jackson-core` classes directly will break — update imports. No official compatibility bridge exists; migration must be done manually. If the project already uses Jackson 3 → proceed. If still on Jackson 2 → flag the migration before adding new Jackson-dependent code. ## Reference Guide Load on demand — don't read all of these upfront. | Topic | Reference | Load when | |-------|-----------|-----------| | Web Layer | `references/web.md` | Controllers, DTO boundary, validation, `ProblemDetail`, pagination, CORS, deprecations | | Data Access | `references/data.md` | JPA / Hibernate pitfalls: N+1, `open-in-view`, `@Transactional` self-invocation, fetch-join + pagination, Hikari tuning | | Security | `references/security.md` | Spring Security 7 `SecurityFilterChain`, CSRF rules, JWT resource server, method security, `/actuator/*` hardening | | Testing | `references/testing.md` | Test slices (`@WebMvcTest` / `@DataJpaTest` / `@RestClientTest`), `@MockitoBean` migration, Testcontainers + `@ServiceConnection` | | Migrations | `references/migrations.md` | Flyway / Liquibase, zero-downtime schema change (expand-contract), baseline-on-migrate, `CREATE INDEX CONCURRENTLY` | | Scheduling & Observability | `references/scheduling-observability.md` | `@Scheduled` in a cluster (ShedLock), Actuator exposure, health probes, Micrometer cardinality, virtual threads trade-offs | | Kotlin | `references/kotlin.md` | `kotlin-spring` / `kotlin-jpa` plugins, `@field:` validation, `suspend` controllers, `data class` vs `@Entity` | | Event-Driven | `references/event-driven.md` | `@TransactionalEventListener`, `@Async` traps, Kafka idempotence, outbox pattern | | Resilience | `references/resilience.md` | Resilience4j annotation order, `fallbackMethod` rules, breaker + retry interaction, distributed vs local rate-limit | | Reactive (WebFlux) | `references/reactive.md` | When WebFlux is the right choice, `.block()` traps, `Schedulers.boundedElastic()`, context propagation, backpressure | | Cloud Native | `references/cloud.md` | `spring.config.import` (not `bootstrap.yml`), `@RefreshScope` limits, Gateway on WebFlux, k8s vs Spring Cloud choice | ## Constraints ### MUST DO | Rule | Correct pattern | |------|-----------------| | Constructor injection | `public MyService(Dep dep) { this.dep = dep; }` — never `@Autowired` on a field | | Validate every mutating endpoint | `@Valid @RequestBody MyRequest req` + Bean Validation annotations on the DTO | | DTOs at the web boundary | Java `record` or Kotlin `data class` — **never** return or accept JPA entities directly | | Type-safe config | `@ConfigurationProperties(prefix = "app")` bound to a record/class, not `@Value("${…}")` scattered across the codebase | | Correct stereotype | `@Service` for business logic, `@Repository` for data, `@RestController` for HTTP, `@Component` only when nothing else fits | | Transaction scope | `@Transactional` only on `public` methods of a Spring-managed bean, called from outside the class (see MUST NOT below) | | Read-only hint | `@Transactional(readOnly = true)` on queries — lets Hibernate skip dirty-checking | | Rollback on checked exceptions | `@Transactional(rollbackFor = Exception.class)` when the method throws checked exceptions you want to roll back | | Global error handling | `@RestControllerAdvice` + `ProblemDetail` (RFC 7807) — never leak stack traces to clients | | Externalize secrets | Env vars or Spring Cloud Config — never commit secrets to `application.properties` / `application.yml` | | Kotlin + Spring | `kotlin("plugin.spring")` always; `kotlin("plugin.jpa")` when JPA is used | | Kotlin validation | `@field:NotBlank` on `data class` properties — bare `@NotBlank` is silently ignored | | Post-commit side effects | `@TransactionalEventListener(phase = AFTER_COMMIT)` for email / Kafka / external calls — never inline after a `save()` inside the same transaction | ### MUST NOT — `@Transactional` pitfalls that break in production - **Self-invocation.** Calling `this.methodWithTransactional()` from another method in the same bean bypasses the proxy — no transaction starts. If you need it, inject `self` (`@Lazy @Autowired MyService self`) or extract the method to a separate bean. - **Private / package-private / `final` methods.** Proxies cannot intercept them. `@Transactional` must be on `public` non-`final` methods. (In Kotlin: add `kotlin-spring` plugin so classes/methods are open.) - **Checked exceptions without `rollbackFor`.** By default Spring rolls back only on `RuntimeException` / `Error`. Declare `@Transactional(rollbackFor = IOException.class)` (or a common superclass) when you want checked exceptions to roll back. - **`@Async` + `@Transactional` on the same method.** The async thread doesn't inherit the transaction context — entity becomes detached, you get `LazyInitializationException` or no transaction at all. Split into two beans or use `@TransactionalEventListener(phase = AFTER_COMMIT)`. - **Writes inside `readOnly = true`.** Hibernate may skip the flush — your update silently disappears. - **`@Transactional` on a `@PostConstruct` method.** Proxy isn't fully initialized yet; the annotation has no effect. ### MUST NOT — general - Field injection (`@Autowired` on fields) — breaks testability and hides required dependencies. - Skipping `@Valid` on API input — request bodies reach your service with whatever the client sent. - Using `@Component` when a more specific stereotype fits. - Mixing blocking and reactive code: no `.block()` / `.toFuture().get()` inside a `Mono` / `Flux` chain; no blocking JDBC inside a WebFlux controller. Wrap unavoidable blocking calls with `Mono.fromCallable(...).subscribeOn(Schedulers.boundedElastic())`. - Storing secrets, connection strings or tokens in `application.properties` / `application.yml` committed to git. - Hardcoding URLs / environment-specific values — use profiles (`application-dev.yml`, `application-prod.yml`) and env vars. - Removed Boot 3.x deprecated APIs — all of these are gone in Boot 4 and will fail to compile: - `WebSecurityConfigurerAdapter` (use `SecurityFilterChain` bean) - `antMatchers(...)` (use `requestMatchers(...)`) - `WebMvcConfigurerAdapter` (implement `WebMvcConfigurer`) - `and()` in `HttpSecurity` DSL (use separate lambda calls) - `@MockBean` / `@SpyBean` (use `@MockitoBean` / `@MockitoSpyBean`) - `authorizeRequests()` (use `authorizeHttpRequests()`) - **Jackson 3 imports**: `com.fasterxml.jackson.*` → `tools.jackson.*`. Don't write new code against Jackson 2 packages on a Boot 4 project. - Undertow embedded server — not supported. Don't add `spring-boot-starter-undertow`. - Returning or accepting JPA entities at the controller layer — leaks persistence details, causes lazy-loading blowups (`could not initialize proxy — no Session`), breaks API contracts on entity refactors. - N+1 queries: `repository.findAll()` followed by accessing `@OneToMany` lazy associations in a loop. Use `@EntityGraph`, `JOIN FETCH`, or projections. See `references/data.md`. - `spring.jpa.open-in-view=true` in production (the Spring Boot default!). Explicitly set it to `false` — OSIV hides lazy-loading bugs and holds the DB connection for the entire HTTP request. ## Output Format When implementing a new feature, deliver in this order: 1. Migration (Flyway / Liquibase) if schema changes are needed. 2. Entity + Repository. 3. Service with `@Transactional` boundaries. 4. DTOs (request + response) as records / data classes. 5. Controller + `@RestControllerAdvice` entries for new exception types. 6. Tests: one `@DataJpaTest` for repository custom queries, one `@WebMvcTest` per controller, one `@SpringBootTest` for the full happy path. 7. One-line summary of the key architectural decisions (why this transaction boundary, why this projection, why this status code).
Voir sur GitHub