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/