Gentleman-Skills spring-boot-3
install
source · Clone the upstream repo
git clone https://github.com/Gentleman-Programming/Gentleman-Skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/Gentleman-Programming/Gentleman-Skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/community/spring-boot-3" ~/.claude/skills/gentleman-programming-gentleman-skills-spring-boot-3 && rm -rf "$T"
manifest:
community/spring-boot-3/SKILL.mdsource content
When to Use
Load this skill when:
- Building a Spring Boot 3.3+ service or API
- Wiring beans with dependency injection
- Defining configuration properties and validation
- Implementing REST controllers and service layers
Critical Patterns
Pattern 1: Constructor injection only
Always use constructor injection; avoid field injection.
Pattern 2: Typed configuration properties
Use @ConfigurationProperties with validation, not scattered @Value.
Pattern 3: Transaction boundaries at service layer
Apply @Transactional on application services, not controllers.
Code Examples
Example 1: Configuration properties with validation
package com.acme.config; import jakarta.validation.constraints.NotBlank; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.validation.annotation.Validated; @Validated @ConfigurationProperties(prefix = "payment") public record PaymentProperties( @NotBlank String provider, @NotBlank String apiKey ) { }
package com.acme; import org.springframework.boot.context.properties.ConfigurationPropertiesScan; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication @ConfigurationPropertiesScan public class Application { }
Example 2: Service with constructor injection + transaction
package com.acme.order.application; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service public final class OrderService { private final OrderRepository repository; public OrderService(OrderRepository repository) { this.repository = repository; } @Transactional public void placeOrder(OrderCommand command) { repository.save(command.toEntity()); } }
Example 3: REST controller with DTO records
package com.acme.order.api; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/orders") public final class OrderController { private final OrderService service; public OrderController(OrderService service) { this.service = service; } @PostMapping public ResponseEntity<OrderResponse> place(@RequestBody OrderRequest request) { service.placeOrder(request.toCommand()); return ResponseEntity.ok(new OrderResponse("ok")); } public record OrderRequest(String sku, int qty) { public OrderCommand toCommand() { return new OrderCommand(sku, qty); } } public record OrderResponse(String status) { } }
Anti-Patterns
Don't: Use field injection
// BAD: field injection @Service public class OrderService { @org.springframework.beans.factory.annotation.Autowired private OrderRepository repository; }
Don't: Scatter configuration with @Value
// BAD: hard to validate and test @Service public class PaymentService { @org.springframework.beans.factory.annotation.Value("${payment.apiKey}") private String apiKey; }
Quick Reference
| Task | Pattern |
|---|---|
| Inject dependencies | Constructor injection only |
| Read config | @ConfigurationProperties + @Validated |
| Transactions | @Transactional on services |
Resources
- Spring Boot Reference: https://docs.spring.io/spring-boot/docs/current/reference/html/
- Spring Framework Reference: https://docs.spring.io/spring-framework/reference/