#spring-statemachine
#spring-statemachine
Вопрос:
С конечным автоматом spring у нас есть состояния и события. Я не смог найти никакой документации о том, возможно ли привязать статические данные к состоянию во время настройки.
Например, если существуют состояния S1 и S2
public void configure(StateMachineStateConfigurer<String, String> states) throws Exception {
states.withStates()
.initial("INIT")
.end("END")
.state("S1", null, exitAction())
.state("S2", entryAction());
}
Если бы мы могли присоединять статические данные во время приведенной выше конфигурации (например, java Map), это могло бы быть полезно в запускаемых действиях (например, entryAction и ExitAction выше)
Я не знаю, возможно ли это как-то сделать.
Ответ №1:
Это достигается с помощью двух объектов в конечном автомате — StateContext и ExtendedState.
StateContext подобен текущему снимку конечного автомата — он передается с помощью различных методов и обратных вызовов, включая действия и средства защиты.
ExtendedState — это, по сути, отображение с переменными.
Вы можете получить ExtendedState
из StateContext
:
context.getExtendedState()
.getVariables().put("mykey", "myvalue");
Поскольку они передаются как часть контекста, вы можете получить доступ к ExtendedState
при каждом действии, переходе, защите и т.д.
Сам объект StateMachine также имеет getExtendedState()
метод.
Это канонический способ передачи статических данных в StateMachine.
Комментарии:
1. Я следил за этим техническим специалистом, чтобы создать сценарий, в котором Action2 нужны данные из Action1. Нормально ли это делать? передача больших объектов в контекст? Спасибо
2. @PascoalEddyBayonne как и большинство ответов: это зависит. Как часто это происходит (например, какова ваша нагрузка на этот экземпляр SM?). Насколько велико значение large? Лучший способ — измерить объем памяти и провести некоторое нагрузочное тестирование. Есть ли у вас альтернативы — например, запись этого состояния в кэш памяти или другой тип хранилища в Action1 и извлечение его в Action2? Как сравниваются два подхода при нагрузочном тестировании, которое соответствует вашему реальному сценарию?
3. спасибо за быстрые ответы. Ну, на самом деле то, что я делаю, — это использую Действия для выполнения некоторой бизнес-логики. Единственный вопрос заключается в передаче данных между действиями. Большой объект я имею в виду любой объект Java, например CreateCreditCardRequest, внутри которого больше объектов. Предположим, я хочу использовать CreateCreditCardRequest в Action2, но мне нужно дополнить его данными, полученными из Action1. Просто это. Я использую контекст для передачи данных (любого размера) между различными действиями. Что вы посоветуете? Еще раз спасибо
4. То, что я делал несколько лет назад — аналогично вашему случаю — это только передавал идентификатор, указывающий на мой объект в контексте SM — и при каждом событии действии в определении SM — получал идентификатор — извлекал объект (это было из кэша JPA L1 или из базы данных для чтения — в зависимости) — изменял объект — сохранял объект. Если мне придется делать это сейчас, у меня, вероятно, будет поток событий журнал событий, применяющий модификацию к объекту в памяти и периодически сохраняющий объект в хранилище. Очевидно, что события будут записываться в журнал событий с опережением записи.