阿超
>
spring-state-machine持久化
天底下只有一个方法可以影响人,就是提到他们的需要,并且让他们知道怎么去获得。——卡耐基
文档如下:
https://docs.spring.io/spring-statemachine/docs/current/reference/#statemachine-examples-datapersist
代码示例如下:
https://github.com/spring-projects/spring-statemachine/tree/main/spring-statemachine-samples/persist
状态机持久化主要解决服务端重启后会话丢失问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 package demo.persist;import static org.assertj.core.api.Assertions.assertThat;import static org.springframework.statemachine.TestUtils.doStartAndAssert;import java.util.ArrayList;import java.util.List;import java.util.concurrent.CountDownLatch;import java.util.concurrent.TimeUnit;import org.junit.jupiter.api.Test;import org.junit.jupiter.api.extension.ExtendWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.statemachine.StateMachine;import org.springframework.statemachine.listener.StateMachineListenerAdapter;import org.springframework.statemachine.state.State;import org.springframework.statemachine.transition.Transition;import org.springframework.test.annotation.DirtiesContext;import org.springframework.test.annotation.DirtiesContext.ClassMode;import org.springframework.test.context.junit.jupiter.SpringExtension;import demo.CommonConfiguration;@ExtendWith(SpringExtension.class) @DirtiesContext(classMode=ClassMode.AFTER_EACH_TEST_METHOD) @SpringBootTest(classes = { CommonConfiguration.class, Application.class, StateMachineCommands.class }) public class PersistTests { @Autowired private StateMachineCommands commands; @Autowired private StateMachine<String, String> machine; @Autowired private Persist persist; @Test public void testNotStarted () throws Exception { assertThat(commands.state()).isEqualTo("No state" ); } @Test public void testInitialState () throws Exception { TestListener listener = new TestListener (); machine.addStateListener(listener); doStartAndAssert(machine); assertThat(listener.stateChangedLatch.await(3 , TimeUnit.SECONDS)).isTrue(); assertThat(listener.stateEnteredLatch.await(3 , TimeUnit.SECONDS)).isTrue(); assertThat(machine.getState().getIds()).containsExactly("PLACED" ); assertThat(listener.statesEntered).hasSize(1 ); assertThat(listener.statesEntered.get(0 ).getId()).isEqualTo("PLACED" ); assertThat(listener.statesExited).isEmpty(); } @Test public void testInitialDbList () { assertThat(persist.listDbEntries()).contains("PLACED" ); } @Test public void testUpdate1 () { persist.change(1 , "PROCESS" ); assertThat(persist.listDbEntries()).contains("id=1, state=PROCESSING" ); } @Test public void testUpdate2 () { persist.change(2 , "SEND" ); assertThat(persist.listDbEntries()).contains("id=2, state=SENT" ); } private static class TestListener extends StateMachineListenerAdapter <String, String> { volatile CountDownLatch stateChangedLatch = new CountDownLatch (1 ); volatile CountDownLatch stateEnteredLatch = new CountDownLatch (1 ); volatile CountDownLatch stateExitedLatch = new CountDownLatch (0 ); volatile CountDownLatch transitionLatch = new CountDownLatch (0 ); volatile List<Transition<String, String>> transitions = new ArrayList <Transition<String, String>>(); List<State<String, String>> statesEntered = new ArrayList <State<String, String>>(); List<State<String, String>> statesExited = new ArrayList <State<String, String>>(); @Override public void stateChanged (State<String, String> from, State<String, String> to) { stateChangedLatch.countDown(); } @Override public void stateEntered (State<String, String> state) { statesEntered.add(state); stateEnteredLatch.countDown(); } @Override public void stateExited (State<String, String> state) { statesExited.add(state); stateExitedLatch.countDown(); } @Override public void transition (Transition<String, String> transition) { transitions.add(transition); transitionLatch.countDown(); } } }