It is a little limited to do interaction with a state machine by either listening its events or using actions with states and transitions. Time to time this approach would be too limited and verbose to create interaction with the application a state machine is working with. For this specific use case we have made a spring style context integration which easily attach state machine functionality into your beans.
@WithStateMachine annotation can be used to associate a state machine with a existing bean. Within this annotation a property’s source and target can be used to qualify a transition. If source and target is left empty then any transition is matched.
@WithStateMachine public class Bean1 { @OnTransition(source = "S1", target = "S2") public void fromS1ToS2() { } @OnTransition public void anyTransition() { } }
Default @OnTransition annotation can’t be used with a state and event enums user have created due to java language limitations, thus string representation have to be used.
Additionally it is possible to access Event Headers
and
ExtendedState
by adding needed arguments to a method. Method
is then called automatically with these arguments.
@WithStateMachine public class Bean4 { @StatesOnTransition(source = States.S1, target = States.S2) public void fromS1ToS2(@EventHeaders Map<String, Object> headers, ExtendedState extendedState) { } }
However if you want to have a type safe annotation it is possible to create a new annotation and use @OnTransition as meta annotation. This user level annotation can make a reference to actual states and events enums and framework will try to match these in a same way.
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @OnTransition public @interface StatesOnTransition { States[] source() default {}; States[] target() default {}; }
Above we created a @StatesOnTransition annotation which defines
source
and target
as a type safe manner.
@WithStateMachine public class Bean2 { @StatesOnTransition(source = States.S1, target = States.S2) public void fromS1ToS2() { } }
In your own bean you can then use this @StatesOnTransition as is and
use type safe source
and target
.