⌂ Index
Kapitel 29 · Architecture

Spring Statemachine für Lebenszyklen und Zustände

Typ: FrameworkVersion 2 ausführlich

Spring Statemachine modelliert Zustände, Events, Guards und Actions für komplexe fachliche Lebenszyklen.

Fachliche Einordnung

Wenn Statusübergänge über viele if/else-Blöcke verstreut sind, werden Regeln unverständlich. Eine Statemachine macht erlaubte Übergänge explizit.

Enterprise-Merksatz: Spring Statemachine modelliert Zustände, Events, Guards und Actions für komplexe fachliche Lebenszyklen.

Technische Darstellung

Current State Event Guard Transition Action Next State
Kernkonzepte
  • State, Event, Transition.
  • Guard als Bedingung für Übergang.
  • Action als technische oder fachliche Reaktion.
  • Persistenz des Maschinenzustands.
  • Visualisierung von Lebenszyklen.
Wann einsetzen?
  • Aufträge, Zahlungen, Tickets oder Anträge haben komplexe Statusflüsse.
  • Du willst Statusregeln zentral testen.
  • Du migrierst alte Statuscode-Tabellen und Stored Procedures.
Typische Fehler und Risiken
  • Statemachine für triviale CRUD-Status verwenden.
  • Actions mit zu viel Fachlogik aufblasen.
  • Persistenz und Nebenwirkungen unklar trennen.
Legacy- und Modernisierungssicht

Status-Spaghetti aus PL/SQL, EJBs oder UI-Logik kann in explizite States/Transitions überführt werden.

Ausführliches Beispiel

Das Beispiel zeigt bewusst nicht nur Annotationen, sondern auch die Verantwortung der Schicht. In echten Projekten sollte der technische Spring-Code an Adapter- oder Konfigurationsrändern bleiben, während die Fachlogik testbar und möglichst frameworkarm bleibt.

@Configuration
@EnableStateMachine
class OrderStateMachineConfiguration extends StateMachineConfigurerAdapter<OrderState, OrderEvent> {
    @Override
    public void configure(StateMachineTransitionConfigurer<OrderState, OrderEvent> transitions) throws Exception {
        transitions
            .withExternal().source(OrderState.DRAFT).target(OrderState.SUBMITTED).event(OrderEvent.SUBMIT)
            .and()
            .withExternal().source(OrderState.SUBMITTED).target(OrderState.PAID).event(OrderEvent.PAY)
                .guard(ctx -> paymentIsValid(ctx));
    }
}
Checkliste für Reviews
  • Ist die Verantwortung des Bausteins klar: Framework steuert Lebenszyklus, Library wird gezielt benutzt?
  • Ist die Fachlogik außerhalb von Controller, Listener, Repository-Implementierung oder Konfiguration?
  • Sind Fehlerfälle, Timeouts, Security, Monitoring und Tests sichtbar modelliert?
  • Gibt es klare Grenzen zwischen DTO, Domäne, Persistence und Infrastruktur?