Spring Boot & Spring Framework
Auto-Configuration verstehen, nicht blind benutzen: Controller, Services, Configuration, Profiles, Actuator.
Spring Boot in Enterprise-Systemen
Spring Boot ist stark, weil es Konventionen, Auto-Configuration, Starter, Actuator, Security-Integration, Testunterstützung und Cloud-Native-Betrieb zusammenbringt. Die Gefahr ist, dass Architekturentscheidungen in zufälligen Annotationen verschwinden. Gute Spring-Systeme halten Fachgrenzen explizit.
| Spring-Baustein | Nutzen | Enterprise-Regel |
|---|---|---|
| @Configuration | Explizite Beans und Adapter verdrahten | Konfiguration ist Infrastruktur, nicht Fachlogik |
| @Service | Use Cases oder technische Services markieren | Nicht jede Klasse mit @Service vollkleben |
| @Transactional | Transaktionsgrenze deklarieren | Anwendungsservice statt Controller |
| Actuator | Health, Metrics, Info, Readiness | Nur sichere Endpunkte extern freigeben |
| Profiles | Runtime-Konfiguration trennen | Keine Fachlogik per Profil verzweigen |
Controller, DTO und Use Case
@RestController
@RequestMapping("/api/orders")
class OrderController {
private final PlaceOrderUseCase placeOrder;
OrderController(PlaceOrderUseCase placeOrder) {
this.placeOrder = placeOrder;
}
@PostMapping
ResponseEntity<OrderResponse> create(@Valid @RequestBody PlaceOrderRequest request) {
OrderId id = placeOrder.handle(request.toCommand());
URI location = URI.create("/api/orders/" + id.value());
return ResponseEntity.created(location).body(new OrderResponse(id.value()));
}
}
Der Controller übersetzt HTTP in einen Use Case. Er sollte nicht entscheiden, wie Preise berechnet, Rechnungen erzeugt oder Events publiziert werden. Diese Entscheidungen gehören in Application Service und Domain.
Spring Configuration als Adapter-Zentrale
@Configuration
class OrderModuleConfiguration {
@Bean
PlaceOrderUseCase placeOrderUseCase(
OrderRepository repository,
DomainEventPublisher eventPublisher,
PricingPolicy pricingPolicy) {
return new PlaceOrderUseCase(repository, eventPublisher, pricingPolicy);
}
@Bean
PricingPolicy pricingPolicy(ProductCatalogClient catalog) {
// Pattern: Adapter + Strategy - Preisstrategie kann pro Kontext ausgetauscht werden.
return new CatalogBackedPricingPolicy(catalog);
}
}
Actuator und Betriebsfähigkeit
Enterprise-Anwendungen müssen betrieblich beobachtbar sein. Readiness bedeutet: Kann diese Instanz Traffic annehmen? Liveness bedeutet: Muss diese Instanz neugestartet werden? Health Checks dürfen nicht zu schwer sein und sollten Abhängigkeiten bewusst modellieren.
management:
endpoints:
web:
exposure:
include: health,info,metrics,prometheus
endpoint:
health:
probes:
enabled: true
show-details: when_authorized