言成言成啊 | Kit Chen's Blog

Spring StateMachine

发布于2021-07-07 23:21:49,更新于2021-08-31 20:43:42,标签:java open spring  文章会持续修订,转载请注明来源地址:https://meethigher.top/blog

一、入门案例

参考demo

  1. sunbufu的源码(主要还是参照这个大佬的源码和博客)
  2. sunbufu的博客
  3. qq

案例流程图如下所示,本案例源码

下面放置关键代码

OrderStateMachineConfig

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
@Configuration
@EnableStateMachine(name="orderStateMachine")
public class OrderStateMachineConfig extends StateMachineConfigurerAdapter<OrderState, OrderEvent> {
public OrderStateMachineConfig() {

}

/**
* 配置状态
*
* @param states
* @throws Exception
*/
@Override
public void configure(StateMachineStateConfigurer<OrderState, OrderEvent> states) throws Exception {
states.withStates()
.initial(OrderState.WAIT_PAY)
.states(EnumSet.allOf(OrderState.class));
}

/**
* 配置转换关系
*
* @param transitions
* @throws Exception
*/
@Override
public void configure(StateMachineTransitionConfigurer<OrderState, OrderEvent> transitions) throws Exception {
transitions
.withExternal().source(OrderState.WAIT_PAY).target(OrderState.WAIT_DELIVER).event(OrderEvent.PAY)
.and()
.withExternal().source(OrderState.WAIT_DELIVER).target(OrderState.WAIT_RECEIVE).event(OrderEvent.DELIVER)
.and()
.withExternal().source(OrderState.WAIT_RECEIVE).target(OrderState.FINISH).event(OrderEvent.RECEIVE);

}
}

OrderStateMachinePersisterConfig

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Configuration
public class OrderStateMachinePersisterConfig {
@Bean
public StateMachinePersister<OrderState, OrderEvent, Order> orderStateMachinePersist() {
return new DefaultStateMachinePersister<>(new StateMachinePersist<OrderState, OrderEvent, Order>() {
@Override
public StateMachineContext<OrderState, OrderEvent> read(Order order) {
return new DefaultStateMachineContext<>(order.getState(), null, null, null);
}

@Override
public void write(StateMachineContext<OrderState, OrderEvent> context, Order order) throws Exception {
order.setState(context.getState());
}
});
}
}

OrderStateMachineHandler

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
@Component
public class OrderStateMachineHandler {
@Autowired
private StateMachine<OrderState, OrderEvent> stateMachine;
@Autowired
private StateMachinePersister<OrderState, OrderEvent, Order> stateMachinePersister;

public synchronized boolean sendEvent(OrderEvent event, Order order) {
boolean result = false;
try {
stateMachine.start();
//设置状态机状态
stateMachinePersister.restore(stateMachine, order);
Message<OrderEvent> eventMessage = MessageBuilder.withPayload(event).setHeader("order", order).build();
result = stateMachine.sendEvent(eventMessage);
//保存状态机状态
stateMachinePersister.persist(stateMachine, order);
} catch (Exception e) {
e.printStackTrace();
} finally {
stateMachine.stop();
}
return result;
}
}

OrderStateMachineListener

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
@Component
@WithStateMachine(name = "orderStateMachine")
public class OrderStateMachineListener {
private final static Logger log= LoggerFactory.getLogger(OrderStateMachineListener.class);
@OnTransition(source = "WAIT_PAY", target = "WAIT_DELIVER")
public boolean pay(Message<OrderEvent> message) {
OrderEvent payload = message.getPayload();
String name = payload.name();
log.info("完成动作---"+name);
return true;
}

@OnTransition(source = "WAIT_DELIVER", target = "WAIT_RECEIVE")
public boolean deliver(Message<OrderEvent> message) {
OrderEvent payload = message.getPayload();
String name = payload.name();
log.info("完成动作---"+name);
return true;
}

@OnTransition(source = "WAIT_RECEIVE", target = "FINISH")
public boolean receive(Message<OrderEvent> message) {
OrderEvent payload = message.getPayload();
String name = payload.name();
log.info("完成动作---"+name);
return true;
}
}

二、状态机

我理解的状态机的作用

  1. 在允许的不同状态间进行切换
  2. 防止在不允许的状态间切换导致的问题

Spring Statemachine各模块作用

模块描述
spring-statemachine-coreSpring 状态机的核心系统。
spring-statemachine-recipes-common不需要核心框架之外的依赖项的常见配方。
spring-statemachine-kryoSpring Statemachine的Kryo序列化器
spring-statemachine-data-commonSpring Data的通用支持模块
spring-statemachine-data-jpaSpring Data JPA的支持模块
spring-statemachine-data-redisSpring Data Redis的支持模块
spring-statemachine-data-mongodbSpring Data MongoDB的支持模块
spring-statemachine-zookeeper分布式状态机的 Zookeeper 集成
spring-statemachine-test状态机测试的支持模块
spring-statemachine-clusterSpring Cloud Cluster 的支持模块。请注意,Spring Cloud Cluster 已被 Spring Integration 取代
spring-statemachine-uml使用 Eclipse Papyrus 进行 UI UML 建模的支持模块
spring-statemachine-autoconfigureSpring Boot 的支持模块
spring-statemachine-bom材料清单pom
spring-statemachine-starterSpring Boot 启动器

2.1 需求

实现一个审批功能,时序图如下。

分为四个模块来完成,启动模块公共模块信息提供者信息管理者。参照IDEA创建多模块SpringBoot项目

导入依赖,版本的选用可以参考官网doc

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
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>top.meethigher.spring.statemachine.enhanced</groupId>
<artifactId>spring-statemachine-enhanced</artifactId>
<version>1.0</version>
<name>spring-statemachine-enhanced</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

<!-- 核心模块 -->
<dependency>
<groupId>org.springframework.statemachine</groupId>
<artifactId>spring-statemachine-core</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
<!-- spring data 公共模块 -->
<dependency>
<groupId>org.springframework.statemachine</groupId>
<artifactId>spring-statemachine-data-common</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
<!-- spring statemachine kryo序列化 -->
<dependency>
<groupId>org.springframework.statemachine</groupId>
<artifactId>spring-statemachine-kryo</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
<!-- spring data jpa -->
<dependency>
<groupId>org.springframework.statemachine</groupId>
<artifactId>spring-statemachine-data-jpa</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
发布:2021-07-07 23:21:49
修改:2021-08-31 20:43:42
链接:https://meethigher.top/blog/2021/spring-statemachine/
标签:java open spring 
付款码 打赏 分享
Shift+Ctrl+1 可控制工具栏