本工程主要演示如何在 Spring Boot 2.x 项目中整合 COLA State Machine,并提供一个基础的示例。
在众多状态机实现中,我们选择了 COLA State Machine,主要基于以下几点考虑:
| 特性 | Spring State Machine | COLA State Machine |
|---|---|---|
| 状态管理 | 有状态 | 无状态 |
| 功能完备性 | 功能完備 | 核心功能完备 |
| 学习曲线 | 较难 | 简单 |
| 性能 | 一般 | 高性能 |
| 可视化 | 不支持 | 支持 PlantUML 导出 |
对于需要快速落地业务、且对性能有较高要求的场景,COLA State Machine 是一个非常合适的选择。其无状态的设计和简洁的 API,能够极大地提升开发效率。
- Event (事件):触发状态变化的动作。
- Transition (流转):表示状态从一个节点到另一个节点的转换过程。
- External Transition (外部流转):两个不同状态之间的流转。
- Internal Transition (内部流转):同一状态下的自我流转。
- Condition (条件):决定状态是否可以流转的前置条件。
- Action (动作):状态流转完成后执行的业务逻辑。
- StateMachine (状态机):管理所有状态和流转的核心引擎。
在 pom.xml 文件中添加以下依赖:
<dependency>
<groupId>com.alibaba.cola</groupId>
<artifactId>cola-component-statemachine</artifactId>
<version>4.3.1</version>
</dependency>通过 @PostConstruct 注解,在 Spring Boot 应用启动时初始化状态机实例。
import com.alibaba.cola.statemachine.Action;
import com.alibaba.cola.statemachine.Condition;
import com.alibaba.cola.statemachine.StateMachine;
import com.alibaba.cola.statemachine.StateMachineFactory;
import com.alibaba.cola.statemachine.builder.StateMachineBuilder;
import com.alibaba.cola.statemachine.builder.StateMachineBuilderFactory;
import com.giga.statemachine.enums.GigaEvents;
import com.giga.statemachine.enums.GigaStates;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Component
public class StateMachineInit {
public static final String MACHINE_ID = "TestStateMachine";
@PostConstruct
private void initStateMachine() {
buildStateMachine(MACHINE_ID);
}
private StateMachine<GigaStates, GigaEvents, StateMachineContext> buildStateMachine(String machineId) {
StateMachineBuilder<GigaStates, GigaEvents, StateMachineContext> builder = StateMachineBuilderFactory.create();
// 定义状态流转
builder.externalTransition()
.from(GigaStates.STATE1)
.to(GigaStates.STATE2)
.on(GigaEvents.EVENT1)
.when(checkCondition())
.perform(doAction());
builder.internalTransition()
.within(GigaStates.STATE2)
.on(GigaEvents.INTERNAL_EVENT)
.when(checkCondition())
.perform(doAction());
// ... 其他状态流转
builder.build(machineId);
StateMachine<GigaStates, GigaEvents, StateMachineContext> stateMachine = StateMachineFactory.get(machineId);
// 生成并打印 PlantUML 状态图
String plantUML = stateMachine.generatePlantUML();
System.out.println(plantUML);
return stateMachine;
}
private Condition<StateMachineContext> checkCondition() {
return context -> {
System.out.println("Checking condition: " + context);
return context.getBusinessService().checkSomething();
};
}
private Action<GigaStates, GigaEvents, StateMachineContext> doAction() {
return (from, to, event, ctx) -> {
ctx.getBusinessService().doSomething();
System.out.println(String.format(
"%s is operating %s from:%s to:%s on:%s",
ctx.getOperator(), ctx.getEntityId(), from, to, event
));
};
}
}运行单元测试 com.giga.ColaStateMachineApplicationTests#testStateMachine,控制台会输出 PlantUML 格式的字符串。将该字符串粘贴到任意在线 PlantUML 工具(如 PlantUML Web Server)即可生成状态流转图,方便地验证状态机逻辑是否符合预期。
- 状态机实例在应用中是单例的。
- 可以将业务相关的 Bean 作为
StateMachineContext的构造参数传入,方便在Condition和Action中调用。