Spring Statemachine结合JPA对接RDBMS持久化完整配置及示例代码求助
基于MySQL的Spring Statemachine持久化完整实现示例
前置依赖
以Maven为例引入所需依赖:
<!-- Spring Statemachine核心 --> <dependency> <groupId>org.springframework.statemachine</groupId> <artifactId>spring-statemachine-core</artifactId> <version>3.2.0</version> </dependency> <!-- Spring Statemachine JDBC持久化支持 --> <dependency> <groupId>org.springframework.statemachine</groupId> <artifactId>spring-statemachine-jdbc</artifactId> <version>3.2.0</version> </dependency> <!-- MySQL驱动 --> <dependency> <groupId>com.mysql</groupId> <artifactId>mysql-connector-j</artifactId> <scope>runtime</scope> </dependency> <!-- JDBC数据源,Spring Boot项目自带,非Boot项目需额外引入 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency>
1. 初始化数据库表结构
Spring Statemachine JDBC模块默认使用以下表结构存储状态机上下文,直接在MySQL库中执行即可:
CREATE TABLE IF NOT EXISTS spring_statemachine ( machine_id VARCHAR(255) NOT NULL, state VARCHAR(255) DEFAULT NULL, state_machine_context BLOB DEFAULT NULL, PRIMARY KEY (machine_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
如需存储扩展状态等复杂信息,可自行调整字段长度或新增自定义字段,默认结构可覆盖大部分常规场景。
2. 基础枚举定义
先定义状态机的状态和事件枚举,以下以订单状态机为例:
// 订单状态枚举 public enum OrderState { CREATED, PAID, DELIVERED, COMPLETED, CANCELLED } // 订单事件枚举 public enum OrderEvent { PAY, DELIVER, COMPLETE, CANCEL }
3. 核心配置类
3.1 数据源配置(application.yml)
spring: datasource: url: jdbc:mysql://localhost:3306/statemachine_demo?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8 username: root password: 你的数据库密码 driver-class-name: com.mysql.cj.jdbc.Driver
3.2 状态机持久化配置
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.statemachine.StateMachinePersist; import org.springframework.statemachine.config.EnableStateMachine; import org.springframework.statemachine.config.StateMachineConfigurerAdapter; import org.springframework.statemachine.config.builders.StateMachineConfigurationConfigurer; import org.springframework.statemachine.config.builders.StateMachineStateConfigurer; import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer; import org.springframework.statemachine.jdbc.JdbcStateMachineRepository; import org.springframework.statemachine.persist.DefaultStateMachinePersister; import org.springframework.statemachine.persist.RepositoryStateMachinePersist; import org.springframework.statemachine.persist.StateMachinePersister; import javax.sql.DataSource; import java.util.EnumSet; @Configuration @EnableStateMachine public class StateMachineConfig extends StateMachineConfigurerAdapter<OrderState, OrderEvent> { private final DataSource dataSource; public StateMachineConfig(DataSource dataSource) { this.dataSource = dataSource; } // 配置JDBC存储仓库 @Bean public JdbcStateMachineRepository<OrderState, OrderEvent> jdbcStateMachineRepository() { JdbcStateMachineRepository<OrderState, OrderEvent> repository = new JdbcStateMachineRepository<>(new JdbcTemplate(dataSource)); // 如需自定义表名可打开以下配置,默认表名为spring_statemachine // repository.setTableName("custom_statemachine_table"); return repository; } // 配置持久化处理器 @Bean public StateMachinePersist<OrderState, OrderEvent, String> stateMachinePersist() { return new RepositoryStateMachinePersist<>(jdbcStateMachineRepository()); } // 配置持久化工具类,第三个泛型参数为业务唯一标识,示例中为订单ID @Bean public StateMachinePersister<OrderState, OrderEvent, String> stateMachinePersister() { return new DefaultStateMachinePersister<>(stateMachinePersist()); } // 状态配置 @Override public void configure(StateMachineStateConfigurer<OrderState, OrderEvent> states) throws Exception { states .withStates() .initial(OrderState.CREATED) .states(EnumSet.allOf(OrderState.class)); } // 状态流转配置 @Override public void configure(StateMachineTransitionConfigurer<OrderState, OrderEvent> transitions) throws Exception { transitions .withExternal() .source(OrderState.CREATED).target(OrderState.PAID).event(OrderEvent.PAY) .and() .withExternal() .source(OrderState.PAID).target(OrderState.DELIVERED).event(OrderEvent.DELIVER) .and() .withExternal() .source(OrderState.DELIVERED).target(OrderState.COMPLETED).event(OrderEvent.COMPLETE) .and() .withExternal() .source(OrderState.CREATED).target(OrderState.CANCELLED).event(OrderEvent.CANCEL); } // 基础配置 @Override public void configure(StateMachineConfigurationConfigurer<OrderState, OrderEvent> config) throws Exception { config .withConfiguration() .autoStartup(true); } }
4. 业务层使用示例
import org.springframework.statemachine.StateMachine; import org.springframework.statemachine.persist.StateMachinePersister; import org.springframework.stereotype.Service; @Service public class OrderService { private final StateMachine<OrderState, OrderEvent> stateMachine; private final StateMachinePersister<OrderState, OrderEvent, String> persister; public OrderService(StateMachine<OrderState, OrderEvent> stateMachine, StateMachinePersister<OrderState, OrderEvent, String> persister) { this.stateMachine = stateMachine; this.persister = persister; } // 新建订单时初始化状态机并持久化 public void createOrder(String orderId) throws Exception { stateMachine.stop(); stateMachine.start(); persister.persist(stateMachine, orderId); } // 触发事件并更新持久化状态 public void triggerEvent(String orderId, OrderEvent event) throws Exception { // 从数据库恢复对应订单的状态机上下文 persister.restore(stateMachine, orderId); // 发送事件触发状态流转 stateMachine.sendEvent(event); // 持久化更新后的状态机上下文 persister.persist(stateMachine, orderId); } // 查询当前订单状态 public OrderState getCurrentState(String orderId) throws Exception { persister.restore(stateMachine, orderId); return stateMachine.getState().getId(); } }
注意事项
- Spring Statemachine版本需要和当前项目的Spring Boot版本兼容,3.x版本对应Spring Boot 3.x,2.x版本对应Spring Boot 2.x
- 如果需要存储扩展状态中的自定义对象,需要确保对象实现了序列化接口
内容的提问来源于stack exchange,提问作者nk_melb
相关产品推荐
相关产品推荐

