18. Context Integration

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.

18.1 Annotation Support

@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.