Part 6 · 1 chapters · ~8 min
Spring Boot End to End
Starters and auto-configuration, application.yml and profiles, REST controllers with records and validation, ProblemDetail errors, Spring Data JPA and Hibernate, transactions, Spring Security with JWT resource servers, Flyway migrations, Actuator health and metrics, and virtual threads.
9
A Spring Boot service
code
@RestController @RequestMapping("/v1/transfers")
class TransferController {
private final TransferService service;
TransferController(TransferService service) { this.service = service; }
record CreateTransfer(@Positive long amountKobo, @NotBlank String to) {}
@PostMapping @ResponseStatus(HttpStatus.CREATED)
TransferView create(@Valid @RequestBody CreateTransfer in, @RequestHeader("Idempotency-Key") String key, @AuthenticationPrincipal Jwt jwt) {
return service.create(jwt.getSubject(), in.amountKobo(), in.to(), key);
}
}
@RestControllerAdvice
class Errors {
@ExceptionHandler(InsufficientFundsException.class)
ProblemDetail insufficient(InsufficientFundsException e) { return ProblemDetail.forStatusAndDetail(HttpStatus.UNPROCESSABLE_ENTITY, e.getMessage()); }
}
# application.yml
spring:
threads.virtual.enabled: true
datasource: { url: jdbc:postgresql://db/ledger, hikari: { maximum-pool-size: 20 } }
jpa: { open-in-view: false } # never keep sessions open across the whole request
security.oauth2.resourceserver.jwt.issuer-uri: https://auth.bank.example
management.endpoints.web.exposure.include: health,info,prometheusA SPRING BOOT REQUEST
DispatcherServlet to controller to service to repository, with Spring wiring everything
swipe the figure sideways, or tap expand for full screen
1/5
the server
Spring Boot embeds Tomcat (or Jetty, Undertow, Netty for WebFlux) in an executable jar; with virtual threads enabled, each request runs on a virtual thread.
embedded server in a fat jarjava -jar ledger.jar