Обнаружение бина в Spring State Machine не работает

В настоящее время я создаю небольшой пример проекта с помощью конечного автомата Spring.

Моя конфигурация:

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

Когда я сейчас пытаюсь внедрить конечный автомат с

@Autowired
StateMachine<States, Events> stateMachine;

IntelliJ дает мне подсказку, что это не может быть автоматически подключено, потому что там нет бобов. Я также получаю исключение, если я запускаю приложение.

Зависимость Gradle:

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'

5 ответов

Для меня проблема была вызвана несоответствием общих параметров типа. Поэтому вместо StateMachineStateConfigurer у меня был StateMachineStateConfigurer, чтобы версия компонента не была определена.

В вашем случае проверьте импорт "States" и импорт "Events", чтобы убедиться, что они являются одинаковыми классами в определении бина и где вы используете его с @Autowired.

Я не знаю, в чем проблема.. Но следующий фрагмент работает для меня.

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

В классе конфигурации вы можете добавить аннотацию @EnableStateMachineFactory и это будет работать,

      @EnableStateMachineFactory
@Configuration
@Log
public class EmployeeStateMachineConfig extends StateMachineConfigurerAdapter<EmployeeStates, EmployeeEvents> {


}

Вы можете попробовать использовать

@EnableStateMachine(name = "myStateMachine")

а также

@Autowired
StateMachine<States, Events> myStateMachine;

У меня та же проблема.

Я сделал это.

Работает

@SpringBootApplication
@EnableStateMachine
public class StateMachineSpringBootApplication {

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

}

config

@Configuration
public class MachineConfigurationCustom extends EnumStateMachineConfigurerAdapter<BookStates, BookEvents> {

    @Bean
    public StateMachine<BookStates, BookEvents> stateMachine(StateMachineListener<BookStates, BookEvents> listener) throws Exception {

        StateMachineBuilder.Builder<BookStates, BookEvents>  builder =
                StateMachineBuilder.builder();

        builder.configureStates()
                .withStates()
                .initial(BookStates.AVAILABLE)
                .states(EnumSet.allOf(BookStates.class));

        builder.configureTransitions()
                .withExternal()
                .source(BookStates.AVAILABLE)
                .target(BookStates.BORROWED)
                .event(BookEvents.BORROW)
                .and()
                .withExternal()
                .source(BookStates.BORROWED)
                .target(BookStates.AVAILABLE)
                .event(BookEvents.RETURN)
                .and()
                .withExternal()
                .source(BookStates.AVAILABLE)
                .target(BookStates.IN_REPAIR)
                .event(BookEvents.START_REPAIR)
                .and()
                .withExternal()
                .source(BookStates.IN_REPAIR)
                .target(BookStates.AVAILABLE)
                .event(BookEvents.END_REPAIR);

        StateMachine<BookStates, BookEvents> stateMachine = builder.build();
        stateMachine.addStateListener(listener);
        return stateMachine;
    }

    @Override
    public void configure(StateMachineConfigurationConfigurer<BookStates, BookEvents> config) throws Exception {
        config.withConfiguration()
                .autoStartup(true)
                .listener(new LoggingMachineListener());
    }


}

слушатель

@Component
public class LoggingMachineListener implements StateMachineListener<BookStates, BookEvents> {
    private static final Logger LOGGER = LoggingUtils.LOGGER;

    @Override
    public void stateChanged(State<BookStates, BookEvents> from, State<BookStates, BookEvents> to) {
        LOGGER.info("State changed from {} to {}", getStateInfo(from), getStateInfo(to));
    }

    @Override
    public void stateEntered(State<BookStates, BookEvents> state) {
        LOGGER.info("Entered state {}", getStateInfo(state));
    }

    @Override
    public void stateExited(State<BookStates, BookEvents> state) {
        LOGGER.info("Exited state {}", getStateInfo(state));
    }

    @Override
    public void stateMachineStarted(StateMachine<BookStates, BookEvents> stateMachine) {
        LOGGER.info("Machine started: {}", stateMachine);
    }

    @Override
    public void stateMachineStopped(StateMachine<BookStates, BookEvents> stateMachine) {
        LOGGER.info("Machine stopped: {}", stateMachine);
    }

    @Override
    public void stateMachineError(StateMachine<BookStates, BookEvents> stateMachine, Exception exception) {
        LOGGER.error("Machine error: {}", stateMachine);
    }

    @Override
    public void extendedStateChanged(Object key, Object value) {
        LOGGER.info("Extended state changed: [{}: {}]", key, value);
    }

......
}

бегун

@Component
public class RunnerStateMachineWithCommandLine implements CommandLineRunner {

    private final StateMachine<BookStates, BookEvents> stateMachine;

    @Autowired
    public RunnerStateMachineWithCommandLine(StateMachine<BookStates, BookEvents> stateMachine) {
        this.stateMachine = stateMachine;
    }

    @Override
    public void run(String... args){
        stateMachine.start();
        stateMachine.sendEvent(BookEvents.RETURN);
        stateMachine.sendEvent(BookEvents.BORROW);
        stateMachine.stop();
    }
}
Другие вопросы по тегам