(1). 什么是状态机(Statemachine)
状态机是一种用来进行对象行为建模的工具,其作用主要是描述对象在它的生命周期内所经历的状态序列,以及如何响应来自外界的各种事件.在电商场景(订单、物流、售后)、社交(IM消息投递)、分布式集群管理(分布式计算平台任务编排)等场景都有大规模的使用.
Spring Statemachine是Spring官方提供的一个框架,供应用程序开发人员在Spring应用程序中使用状态机.支持状态的嵌套(substate),状态的并行(parallel,fork,join)、子状态机等等.
(2). 定义状态
public enum OrderStates {
UNPAID, // 待支付
WAITING_FOR_RECEIVE, // 待收货
DONE // 结束
}
(3). 定义事件
public enum OrderEvents {
PAY, // 支付
RECEIVE // 收货
}
(4). 配置状态
@Configuration
@EnableStateMachine(name="orderSingleMachine")
public class StateMachineConfig extends EnumStateMachineConfigurerAdapter<OrderStates, OrderEvents> {
private Logger logger = LoggerFactory.getLogger(getClass());
@Override
public void configure(StateMachineStateConfigurer<OrderStates, OrderEvents> states) throws Exception {
states.withStates() // 初始状态
.initial(OrderStates.UNPAID)
// 配置所有状态
.states(EnumSet.allOf(OrderStates.class));
}
@Override
public void configure(StateMachineTransitionConfigurer<OrderStates, OrderEvents> transitions) throws Exception {
transitions.withExternal()
// 待支付 --> 待收货 (触发支付事件)
.source(OrderStates.UNPAID).target(OrderStates.WAITING_FOR_RECEIVE).event(OrderEvents.PAY)
.and()
.withExternal()
// 待收货 --> 结束(触发收货事件)
.source(OrderStates.WAITING_FOR_RECEIVE).target(OrderStates.DONE).event(OrderEvents.RECEIVE);
}
}
(5). 配置状态转换的事件
@WithStateMachine(name="orderSingleMachine")
public class OrderSingleEventConfig {
private Logger logger = LoggerFactory.getLogger(getClass());
/**
* 当前状态UNPAID
*/
@OnTransition(target = "UNPAID")
public void create() {
logger.info("---订单创建,待支付---");
}
/**
* UNPAID->WAITING_FOR_RECEIVE 执行的动作
*/
@OnTransition(source = "UNPAID", target = "WAITING_FOR_RECEIVE")
public void pay() {
logger.info("---用户完成支付,待收货---");
}
/**
* WAITING_FOR_RECEIVE->DONE 执行的动作
*/
@OnTransition(source = "WAITING_FOR_RECEIVE", target = "DONE")
public void receive() {
logger.info("---用户已收货,订单完成---");
}
}
(6). Controller
@RestController
@RequestMapping("/statemachine")
public class StateMachineController {
@Autowired
private StateMachine orderSingleMachine;
@RequestMapping("/testSingleOrderState")
public void testSingleOrderState() throws Exception {
// 创建流程
orderSingleMachine.start();
// 触发PAY事件
orderSingleMachine.sendEvent(OrderEvents.PAY);
// 触发RECEIVE事件
orderSingleMachine.sendEvent(OrderEvents.RECEIVE);
// 获取最终状态
System.out.println("最终状态:" + orderSingleMachine.getState().getId());
} // end testSingleOrderState
}
(7). 依赖配置
<properties>
<java.version>1.8</java.version>
<spring-statemachine.version>2.0.1.RELEASE</spring-statemachine.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.statemachine</groupId>
<artifactId>spring-statemachine-bom</artifactId>
<version>${spring-statemachine.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.statemachine</groupId>
<artifactId>spring-statemachine-starter</artifactId>
</dependency>
(8). 测试
lixin-macbook:~ lixin$ curl http://localhost:9991/statemachine/testSingleOrderState
2022-09-03 13:45:34.733 INFO 1462 --- [nio-9991-exec-2] tConfig$$EnhancerBySpringCGLIB$$9994113f : ---订单创建,待支付---
2022-09-03 13:45:34.743 INFO 1462 --- [nio-9991-exec-2] o.s.s.support.LifecycleObjectSupport : started org.springframework.statemachine.support.DefaultStateMachineExecutor@40751c49
2022-09-03 13:45:34.743 INFO 1462 --- [nio-9991-exec-2] o.s.s.support.LifecycleObjectSupport : started DONE UNPAID WAITING_FOR_RECEIVE / UNPAID / uuid=bf21a999-a468-4c4b-8502-3a653247a6be / id=null
2022-09-03 13:45:34.758 INFO 1462 --- [nio-9991-exec-2] tConfig$$EnhancerBySpringCGLIB$$9994113f : ---用户完成支付,待收货---
2022-09-03 13:45:34.760 INFO 1462 --- [nio-9991-exec-2] tConfig$$EnhancerBySpringCGLIB$$9994113f : ---用户已收货,订单完成---
最终状态:DONE
(9). 总结
先有一个简单的入门,后面,会对源码进行剖析.