StateMachine - действия по изменению состояний - PullRequest
0 голосов
/ 06 июня 2019

Я написал реализацию конечного автомата, используя руководство Spring.

Но я не могу добиться какой-либо реакции на изменение состояния, хотя сами состояния меняются успешно.Возможно, я неправильно понял цель класса Бобов?Мне нужно добиться автоматического выполнения методов closeDoor () и startMoving () при изменении состояния.

Эти сообщения в методах на консоли не отображаются:

import org.springframework.statemachine.annotation.OnTransition;
import org.springframework.statemachine.annotation.WithStateMachine;

@WithStateMachine
public class Beans {

  @OnTransition(target = "CLOSED_DOOR")
  void closeDoor() {
      System.out.println("closeDoor method");
  }

  @OnTransition(target = "GOING")
  void startMoving() {
      System.out.println("startMoving method");
  }
}

Конфигурация:

import org.springframework.statemachine.config.EnableStateMachine;
import org.springframework.statemachine.config.EnumStateMachineConfigurerAdapter;
import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;;

import java.util.EnumSet;


@org.springframework.context.annotation.Configuration
@EnableStateMachine
public class Configuration extends EnumStateMachineConfigurerAdapter<States, Events> {
    @Override
    public void configure(StateMachineStateConfigurer<States, Events> states)
            throws Exception {
        states
                .withStates()
                .initial(States.STAY)
                .states(EnumSet.allOf(States.class));
    }

    @Override
    public void configure(StateMachineTransitionConfigurer<States, Events> transitions)
            throws Exception {
        transitions
                .withExternal()
                .source(States.STAY).target(States.CLOSED_DOOR)
                .event(Events.CLOSE_DOOR)
                .and()
                .withExternal()
                .source(States.CLOSED_DOOR).target(States.GOING)
                .event(Events.MOVE);
    }
}

И запуск (состояния отображаются корректно в консоли, согласно событиям):

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.statemachine.StateMachine;

public class App {
    @Autowired
    static StateMachine<States, Events> stateMachine;

    public static void main(String[] args) {

        stateMachine = Builder.getMachine();
        stateMachine.start();

        stateMachine.sendEvent(Events.CLOSE_DOOR);
        System.out.println(stateMachine.getState()); // ObjectState [getIds()=[CLOSED_DOOR]

        stateMachine.sendEvent(Events.MOVE);
        System.out.println(stateMachine.getState()); // ObjectState [getIds()=[GOING]
    }

Зависимость только одна.

<dependency>
    <groupId>org.springframework.statemachine</groupId>
    <artifactId>spring-statemachine-core</artifactId>
    <version>2.1.3.RELEASE</version>
</dependency>

Что я делаю не так?

1 Ответ

3 голосов
/ 07 июня 2019

Наконец-то мне удалось заставить его работать.Вашей проблемой был механизм Spring DI.Вы пытались использовать @WithStateMachine для включения прослушивателей перехода, но затем вы использовали .getMachine() для создания машинного объекта.Это не будет работать так, вам нужно решить, хотите ли вы использовать Spring Context или нет.Я создал решение с использованием контекста, но вы также можете оставить его и использовать только ручной сборщик, но тогда вам нужно будет изменить слушателей на использование ручного метода вместо аннотаций Spring Context.

Измените вашОсновной класс:

public class App {

    public static void main(String[] args) {

        ConfigurableApplicationContext context = new AnnotationConfigApplicationContext("machine");
        final StateMachine<States, Events> stateMachine = context.getBean(StateMachine.class);

        stateMachine.start();
        System.out.println(stateMachine.getState()); // ObjectState [getIds()=[STAY]

        stateMachine.sendEvent(Events.CLOSE_DOOR);
        System.out.println(stateMachine.getState()); // ObjectState [getIds()=[CLOSED_DOOR]

        stateMachine.sendEvent(Events.MOVE);
        System.out.println(stateMachine.getState()); // ObjectState [getIds()=[GOING]
    }
}

Дайте мне знать, работает ли он для вас и понимаете ли вы это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...