<dependency>
<groupId>org.springframework.statemachine</groupId>
<artifactId>spring-statemachine-core</artifactId>
<version>2.0.1.RELEASE</version>
</dependency>
// 作为数据源
public class Data {
public static List<Order> orderList = new ArrayList<>();
public static void create(Order order) {
orderList.add(order);
}
public static Order getById(String id) {
return orderList.stream().filter(item -> Objects.equals(id, item.getId())).findFirst().orElse(null);
}
public static void update(Order order) {
orderList.stream().filter(item -> Objects.equals(order.getId(), item.getId())).findFirst().ifPresent(
item -> item.setStatus(order.getStatus()));
}
}
// 订单实体
public class Order {
private String id;
private OrderStatus status;
}
/**
* @author yangxj
* @date 2023/10/16 10:37
* 状态机配置
*/
@Configuration
@EnableStateMachine(name = "orderStatemachine")
public class OrderStatemachineConfig extends StateMachineConfigurerAdapter<OrderStatus,OrderStatusChangeEvent> {
@Bean(name = "stateMachinePersister")
public StateMachinePersister<OrderStatus, OrderStatusChangeEvent, String> getPersister() {
return new DefaultStateMachinePersister<>(new StateMachinePersist<OrderStatus, OrderStatusChangeEvent, String>() {
@Override
public void write(StateMachineContext<OrderStatus, OrderStatusChangeEvent> context, String contextObj) throws Exception {
map.put(contextObj, context);
}
@Override
public StateMachineContext<OrderStatus, OrderStatusChangeEvent> read(String contextObj) throws Exception {
return map.get(contextObj);
}
Map<String, StateMachineContext<OrderStatus, OrderStatusChangeEvent>> map = new HashMap<>();
});
}
/**
* 配置状态
*/
@Override
public void configure(StateMachineStateConfigurer<OrderStatus, OrderStatusChangeEvent> states) throws Exception {
states.withStates()
.initial(OrderStatus.WAIT_PAYMENT)
.states(EnumSet.allOf(OrderStatus.class));
}
/**
* 配置转换事件
*/
@Override
public void configure(StateMachineTransitionConfigurer<OrderStatus, OrderStatusChangeEvent> transitions) throws Exception {
transitions
//支付事件:待支付-》待发货
.withExternal().source(OrderStatus.WAIT_PAYMENT).target(OrderStatus.WAIT_DELIVER).event(OrderStatusChangeEvent.PAYED_EVENT)
.and()
//发货事件:待发货-》待收货
.withExternal().source(OrderStatus.WAIT_DELIVER).target(OrderStatus.WAIT_RECEIVE).event(OrderStatusChangeEvent.DELIVERED_EVENT)
.and()
//收货事件:待收货-》已完成
.withExternal().source(OrderStatus.WAIT_RECEIVE).target(OrderStatus.FINISH).event(OrderStatusChangeEvent.RECEIVED_EVENT);
}
}
// 订单状态枚举
public enum OrderStatus {
WAIT_PAYMENT(1, "待支付"),
WAIT_DELIVER(2, "待发货"),
WAIT_RECEIVE(3, "待收货"),
FINISH(4, "已完成");
private final Integer key;
private final String name;
OrderStatus(Integer key, String name) {
this.key = key;
this.name = name;
}
public Integer getKey() {
return key;
}
public String getName() {
return name;
}
}
// 订单状态改变事件
public enum OrderStatusChangeEvent {
// 支付,发货,确认收货
PAYED_EVENT,
DELIVERED_EVENT,
RECEIVED_EVENT;
}
// 事件监听处理
@WithStateMachine(name = "orderStatemachine")
@Slf4j
public class OrderStatusChangeEventListener {
@OnTransition(source = "WAIT_PAYMENT", target = "WAIT_DELIVER")
public boolean payTransition(Message<OrderStatusChangeEvent> message) {
Order order = (Order) message.getHeaders().get("order");
log.info("支付,状态机反馈信息:{}", message.getHeaders());
//更新订单
order.setStatus(OrderStatus.WAIT_DELIVER);
Data.update(order);
return true;
}
@OnTransition(source = "WAIT_DELIVER", target = "WAIT_RECEIVE")
public boolean deliverTransition(Message<OrderStatusChangeEvent> message) {
Order order = (Order) message.getHeaders().get("order");
log.info("发货,状态机反馈信息:{}", message.getHeaders());
//更新订单
order.setStatus(OrderStatus.WAIT_RECEIVE);
Data.update(order);
return true;
}
@OnTransition(source = "WAIT_RECEIVE", target = "FINISH")
public boolean receiveTransition(Message<OrderStatusChangeEvent> message) {
Order order = (Order) message.getHeaders().get("order");
log.info("确认收货,状态机反馈信息:{}", message.getHeaders());
//更新订单
order.setStatus(OrderStatus.FINISH);
Data.update(order);
return true;
}
}
@RestController
@RequestMapping("/order")
public class OrderController {
@Resource
private OrderService orderService;
/**
* 根据id查询订单
*
* @return
*/
@RequestMapping("/getById")
public Order getById(@RequestParam("id") String id) {
//根据id查询订单
Order order = orderService.getById(id);
return order;
}
/**
* 创建订单
*
* @return
*/
@RequestMapping("/create")
public String create(@RequestBody Order order) {
//创建订单
orderService.create(order);
return "sucess";
}
/**
* 对订单进行支付
*
* @param id
* @return
*/
@RequestMapping("/pay")
public String pay(@RequestParam("id") String id) {
//对订单进行支付
orderService.pay(id);
return "success";
}
/**
* 对订单进行发货
*
* @param id
* @return
*/
@RequestMapping("/deliver")
public String deliver(@RequestParam("id") String id) {
//对订单进行确认收货
orderService.deliver(id);
return "success";
}
/**
* 对订单进行确认收货
*
* @param id
* @return
*/
@RequestMapping("/receive")
public String receive(@RequestParam("id") String id) {
//对订单进行确认收货
orderService.receive(id);
return "success";
}
}
/**
* @author yangxj
* @date 2023/10/16 10:55
*/
@Slf4j
@Service
public class OrderService {
@Resource
StateMachine<OrderStatus, OrderStatusChangeEvent> orderStateMachine;
@Resource
StateMachinePersister<OrderStatus, OrderStatusChangeEvent, String> stateMachinePersister;
/**
* 创建订单
*
* @param order
* @return
*/
public Order create(Order order) {
order.setStatus(OrderStatus.WAIT_PAYMENT);
Data.create(order);
return order;
}
/**
* 对订单进行支付
*
* @param id
* @return
*/
public Order pay(String id) {
log.info("线程名称:{},尝试支付,订单号:{}", Thread.currentThread().getName(), id);
Order order = Data.getById(id);
if (!sendEvent(OrderStatusChangeEvent.PAYED_EVENT, order)) {
log.error("线程名称:{},支付失败, 状态异常,订单信息:{}", Thread.currentThread().getName(), order);
throw new RuntimeException("支付失败, 订单状态异常");
}
return order;
}
/**
* 对订单进行发货
*
* @param id
* @return
*/
public Order deliver(String id) {
Order order = Data.getById(id);
log.info("线程名称:{},尝试发货,订单号:{}", Thread.currentThread().getName(), id);
if (!sendEvent(OrderStatusChangeEvent.DELIVERED_EVENT, order)) {
log.error("线程名称:{},发货失败, 状态异常,订单信息:{}", Thread.currentThread().getName(), order);
throw new RuntimeException("发货失败, 订单状态异常");
}
return order;
}
/**
* 对订单进行确认收货
*
* @param id
* @return
*/
public Order receive(String id) {
Order order = Data.getById(id);
log.info("线程名称:{},尝试收货,订单号:{}", Thread.currentThread().getName(), id);
if (!sendEvent(OrderStatusChangeEvent.RECEIVED_EVENT, order)) {
log.error("线程名称:{},收货失败, 状态异常,订单信息:{}", Thread.currentThread().getName(), order);
throw new RuntimeException("收货失败, 订单状态异常");
}
return order;
}
/**
* 发送订单状态转换事件
* synchronized修饰保证这个方法是线程安全的
*
* @param changeEvent
* @param order
* @return
*/
private synchronized boolean sendEvent(OrderStatusChangeEvent changeEvent, Order order) {
boolean result = false;
try {
// 状态机重置
stateMachinePersister.restore(orderStateMachine, order.getId());
Message<OrderStatusChangeEvent> message = MessageBuilder.withPayload(changeEvent).setHeader("order", order).build();
result = orderStateMachine.sendEvent(message);
// 状态机持久化
stateMachinePersister.persist(orderStateMachine, order.getId());
} catch (Exception e) {
log.error("订单操作失败, order: {}", order, e);
} finally {
orderStateMachine.stop();
}
return result;
}
public Order getById(String id) {
return Data.getById(id);
}
}