7. Developing your first Spring Statemachine application

Let’s start by creating a simple Spring Boot Application class implementing CommandLineRunner.

@SpringBootApplication
public class Application implements CommandLineRunner {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

Add states and events:

public static enum States {
    SI, S1, S2
}

public static enum Events {
    E1, E2
}

Add state machine configuration:

@Configuration
@EnableStateMachine
static class StateMachineConfig
        extends EnumStateMachineConfigurerAdapter<States, Events> {

    @Override
    public void configure(StateMachineConfigurationConfigurer<States, Events> config)
            throws Exception {
        config
            .withConfiguration()
                .autoStartup(true)
                .listener(listener());
    }

    @Override
    public void configure(StateMachineStateConfigurer<States, Events> states)
            throws Exception {
        states
            .withStates()
                .initial(States.SI)
                    .states(EnumSet.allOf(States.class));
    }

    @Override
    public void configure(StateMachineTransitionConfigurer<States, Events> transitions)
            throws Exception {
        transitions
            .withExternal()
                .source(States.SI).target(States.S1).event(Events.E1)
                .and()
            .withExternal()
                .source(States.S1).target(States.S2).event(Events.E2);
    }

    @Bean
    public StateMachineListener<States, Events> listener() {
        return new StateMachineListenerAdapter<States, Events>() {
            @Override
            public void stateChanged(State<States, Events> from, State<States, Events> to) {
                System.out.println("State change to " + to.getId());
            }
        };
    }
}

Implement CommandLineRunner, autowire StateMachine:

@Autowired
private StateMachine<States, Events> stateMachine;

@Override
public void run(String... args) throws Exception {
    stateMachine.sendEvent(Events.E1);
    stateMachine.sendEvent(Events.E2);
}

Depending whether you build your application using Gradle or Maven it’s run java -jar build/libs/gs-statemachine-0.1.0.jar or java -jar target/gs-statemachine-0.1.0.jar respectively.

What is expected for running this command is a normal Spring Boot output but if you look closely you see lines:

State change to SI
State change to S1
State change to S2