spring状态机(不太优雅)笔记

📅 2026/7/18 8:56:21
spring状态机(不太优雅)笔记
文章目录什么是状态机事件、动作、业务的区别普通逻辑和状态机的区别集成及使用引入maven依赖定义状态枚举定义事件枚举初始化订单的状态集合以及状态转移事件状态转移的监听器测试听到这个名词一愣但是很快反应过来了就是状态和逻辑控制名词化了。当然和普通逻辑相比可不是改个名字而已有很多不同。什么是状态机Java状态机是一种用于描述系统状态转换的模型通过定义状态、事件、动作和转换规则来控制程序行为。其核心要素如下**状态States**系统可能处于的固定状态如订单状态中的已支付、“已发货等 。 ‌**事件Events**触发状态转换的外部或内部信号如支付”、“取消等操作 。 ‌**动作Actions**状态转换时执行的操作例如更新状态字段或记录日志 。 ‌**转换Transitions**定义事件触发下状态转移的规则例如支付成功事件将待支付状态转为支付成功”。这么看是否还得维护个状态表看起来才比较清楚。事件、动作、业务的区别这几个概念容易混淆。事件表示触发。动作要做的操作业务包含(事件动作)当然也可能有其他操作。普通逻辑和状态机的区别名称普通逻辑状态机逻辑清晰度需要if else来实现逻辑判断可读性差状态机通过预定义状态和事件将状态转换规则显式化避免冗余的条件判断可读性强。扩展性需要在原代码上修改逻辑易出错扩展性差。新增状态或事件时只需扩展状态机配置无需修改现有代码。线程安全支持需手动处理同步问题如使用synchronized或Lock实现复杂且易出错。状态机框架如Spring StateMachine内置线程同步机制确保并发场景下状态一致性。业务解耦状态处理常耦合在业务方法内难以独立测试。 ‌状态机将状态逻辑与业务代码分离便于测试和复用。可视化配置普通逻辑需通过代码硬编码状态转换可读性差。 ‌框架支持通过代码或配置文件定义状态机直观展示状态迁移路径。集成及使用引入maven依赖dependencygroupIdorg.springframework.statemachine/groupIdartifactIdspring-statemachine-core/artifactIdversion2.0.0.RELEASE/version/dependency!-- uml to code --dependencygroupIdorg.springframework.statemachine/groupIdartifactIdspring-statemachine-uml/artifactIdversion2.0.0.RELEASE/version/dependency定义状态枚举代码publicenumStates{UNPAID,// 待支付WAITING_FOR_RECEIVE,// 待收货DONE// 结束}定义事件枚举代码publicenumEvents{PAY,// 支付RECEIVE// 收货}初始化订单的状态集合以及状态转移事件代码publicclassStateMachineConfigextendsEnumStateMachineConfigurerAdapterStates,Events{privateLoggerLOGGERLoggerFactory.getLogger(getClass());Overridepublicvoidconfigure(StateMachineStateConfigurerStates,Eventsstates)throwsException{states.withStates().initial(States.UNPAID).states(EnumSet.allOf(States.class));}Overridepublicvoidconfigure(StateMachineTransitionConfigurerStates,Eventstransitions)throwsException{transitions.withExternal().source(States.UNPAID).target(States.WAITING_FOR_RECEIVE).event(Events.PAY).and().withExternal().source(States.WAITING_FOR_RECEIVE).target(States.DONE).event(Events.RECEIVE);}//守护BeanpublicGuardStates,Eventsguard(){returnnewGuardStates,Events(){publicbooleanevaluate(StateContextStates,Eventscontext){returntrue;}};}状态转移的监听器WithStateMachinepublicclassEventListener{privateLoggerLOGGERLoggerFactory.getLogger(getClass());OnTransition(targetUNPAID)publicvoidcreate(){//此处可以执行具体业务逻辑处理LOGGER.info(--------------------订单创建待支付-----------------------);}OnTransition(sourceUNPAID,targetWAITING_FOR_RECEIVE)publicvoidpay(){//此处可以执行具体业务逻辑处理LOGGER.info(--------------------用户完成支付待收货--------------------);}OnTransition(sourceWAITING_FOR_RECEIVE,targetDONE)publicvoidreceive(){//此处可以执行具体业务逻辑处理LOGGER.info(--------------------用户已收货订单完成----------------------);}}测试测试类代码RunWith(SpringRunner.class)SpringBootTestpublicclassApplicationTests{TestpublicvoidcontextLoads(){}AutowiredprivateStateMachineStates,EventsstateMachine;Testpublicvoidtest()throwsException{stateMachine.start();stateMachine.sendEvent(Events.PAY);stateMachine.sendEvent(Events.RECEIVE);}}1.只运行启动Testpublicvoidtest()throwsException{stateMachine.start();//springboot启动时开启 待支付//stateMachine.sendEvent(Events.PAY); //支付操作 待收货//stateMachine.sendEvent(Events.RECEIVE); //收货操作 结束}2.运行启动与支付操作Testpublicvoidtest()throwsException{stateMachine.start();//springboot启动时开启 待支付//stateMachine.sendEvent(Events.PAY); //支付操作 待收货//stateMachine.sendEvent(Events.RECEIVE); //收货操作 结束}3.全部执行Testpublicvoidtest()throwsException{stateMachine.start();//springboot启动时开启 待支付stateMachine.sendEvent(Events.PAY);//支付操作 待收货stateMachine.sendEvent(Events.RECEIVE);//收货操作 结束}