javaspringspring-bootspring-statemachine

Spring state machine bean detection not working


I'm currently building up a little sample project with Spring state machine.

My configuration:

@Configuration
@EnableStateMachine
public class StateMachineConfiguration extends EnumStateMachineConfigurerAdapter<States, Events> {

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

    @Override
    public void configure(StateMachineTransitionConfigurer<States, Events> transitions)
            throws Exception {
        transitions
                .withExternal()
                .source(States.LOCKED)
                .target(States.UNLOCKED)
                .event(Events.COIN)
                .and()
                .withExternal()
                .source(States.UNLOCKED)
                .target(States.LOCKED)
                .event(Events.PUSH);
    }

    @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());
            }
        };
    }
}

When I now try to inject the state machine with

@Autowired
StateMachine<States, Events> stateMachine;

IntelliJ gives me the hint, that this could not be autowired because no bean is there. I also get an exception if I run the Application.

The gradle dependency:

compile 'org.springframework.statemachine:spring-statemachine-core:2.0.1.
compile group: 'org.springframework.boot', name: 'spring-boot-starter', version: '2.0.1.RELEASE'
compile group: 'org.springframework.shell', name: 'spring-shell-starter', version: '2.0.1.RELEASE'
compile group: 'org.springframework.statemachine', name: 'spring-statemachine-boot', version: '1.2.11.RELEASE'

Solution

  • I don't know what the problem was.. But the following snippet works for me.

    @Configuration
    @EnableStateMachine
    public class StateMachineConfiguration {
    
        private final Logger logger = LoggerFactory.getLogger(this.getClass());
    
        @Bean
        public StateMachine<States, Events> stateMachine(StateMachineListener<States, Events> listener) throws Exception {
            StateMachineBuilder.Builder<States, Events> builder = StateMachineBuilder.builder();
    
            builder.configureStates()
                .withStates()
                .initial(States.LOCKED)
                .states(EnumSet.allOf(States.class));
    
            builder.configureTransitions()
                .withExternal()
                .source(States.LOCKED)
                .target(States.UNLOCKED)
                .event(Events.COIN)
                .and()
                .withExternal()
                .source(States.UNLOCKED)
                .target(States.LOCKED)
                .event(Events.PUSH);
    
            StateMachine<States, Events> stateMachine = builder.build();
            stateMachine.addStateListener(listener);
            return stateMachine;
        }
    
        @Bean
        public StateMachineListener<States, Events> listener() {
            return new StateMachineListenerAdapter<States, Events>() {
                @Override
                public void stateChanged(State<States, Events> from, State<States, Events> to) {
                    logger.info("State change to " + to.getId());
                }
            };
        }
    }