摘要
并没有深入学习,根据网上一些搜到的demo简单上手写了一下
Spring Statemachine 是应用程序开发人员在 Spring 应用程序中使用状态机概念的框架。
正文
一、入门案例
参考demo
- sunbufu的源码(主要还是参照这个大佬的源码和博客)
- sunbufu的博客
- 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;
}
}
|
二、状态机
我理解的状态机的作用
- 在允许的不同状态间进行切换
- 防止在不允许的状态间切换导致的问题
Spring Statemachine各模块作用
| 模块 | 描述 |
|---|
spring-statemachine-core | Spring 状态机的核心系统。 |
spring-statemachine-recipes-common | 不需要核心框架之外的依赖项的常见配方。 |
spring-statemachine-kryo | Spring Statemachine的Kryo序列化器 |
spring-statemachine-data-common | Spring Data的通用支持模块 |
spring-statemachine-data-jpa | Spring Data JPA的支持模块 |
spring-statemachine-data-redis | Spring Data Redis的支持模块 |
spring-statemachine-data-mongodb | Spring Data MongoDB的支持模块 |
spring-statemachine-zookeeper | 分布式状态机的 Zookeeper 集成 |
spring-statemachine-test | 状态机测试的支持模块 |
spring-statemachine-cluster | Spring Cloud Cluster 的支持模块。请注意,Spring Cloud Cluster 已被 Spring Integration 取代 |
spring-statemachine-uml | 使用 Eclipse Papyrus 进行 UI UML 建模的支持模块 |
spring-statemachine-autoconfigure | Spring Boot 的支持模块 |
spring-statemachine-bom | 材料清单pom |
spring-statemachine-starter | Spring 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>
|