Understand the fundamentals of state machines, including their mathematical foundations and how to use them in Spring Boot.
A state machine is a computational model that can be in exactly one of a finite number of states at any given time.
A state machine can be formally defined as a 5-tuple:
M = (Q, Σ, δ, q₀, F)
Q = {DRAFT, REVIEW, APPROVED, REJECTED}
Σ = {SUBMIT, APPROVE, REJECT, EDIT}
δ(DRAFT, SUBMIT) → REVIEW
δ(REVIEW, APPROVE) → APPROVED
δ(REVIEW, REJECT) → REJECTED
δ(REJECTED, EDIT) → DRAFT
q₀ = DRAFT
F = {APPROVED, REJECTED}
spring-statemachine-core
as a dependency.StateMachineConfigurerAdapter
.Java Example:
@Configuration
@EnableStateMachine
public class StateMachineConfig extends StateMachineConfigurerAdapter {
@Override
public void configure(StateMachineStateConfigurer states) throws Exception {
states.withStates()
.initial(State.DRAFT)
.state(State.REVIEW)
.end(State.APPROVED)
.end(State.REJECTED);
}
@Override
public void configure(StateMachineTransitionConfigurer transitions) throws Exception {
transitions
.withExternal().source(State.DRAFT).target(State.REVIEW).event(Event.SUBMIT)
.and()
.withExternal().source(State.REVIEW).target(State.APPROVED).event(Event.APPROVE)
.and()
.withExternal().source(State.REVIEW).target(State.REJECTED).event(Event.REJECT)
.and()
.withExternal().source(State.REJECTED).target(State.DRAFT).event(Event.EDIT);
}
}
With Mono:
Mono.just(Event.SUBMIT)
.doOnNext(event -> stateMachine.sendEvent(event))
.subscribe();
With Flux:
Flux.just(Event.SUBMIT, Event.APPROVE)
.delayElements(Duration.ofSeconds(1))
.doOnNext(event -> stateMachine.sendEvent(event))
.subscribe();
.withExternal()
.source(State.DRAFT)
.target(State.REVIEW)
.event(Event.SUBMIT)
.guard(ctx -> isValid())
.action(ctx -> log.info("Transitioned to REVIEW"));