本文将以电商项目中的订单状态转换这个典型的场景。从订单的创建到支付、发货、完成等状态来使用状态机进行管理。如果使用传统的if-else或者switch语句来管理这些状态,代码会变得非常臃肿且难以维护。而状态机提供了一种更加结构化和可维护的方式来管理这些状态转换。
SpringBoot提供了对状态机的良好支持,我们可以通过添加相关依赖和配置来轻松集成状态机。在项目中,我选择了Spring Statemachine作为状态机框架,它提供了丰富的功能和灵活的扩展性。
下面我们就来编写Spring Boot集成Spring Statemachine的简单示例代码吧。
<dependencies>
<!-- 其他依赖 -->
<!-- Spring Statemachine -->
<dependency>
<groupId>org.springframework.statemachine</groupId>
<artifactId>spring-statemachine-core</artifactId>
<version>2.3.1</version>
</dependency>
</dependencies>
// 定义订单状态
public enum OrderState {
CREATED,
PAID,
SHIPPED,
COMPLETED
}
// 定义订单事件
public enum OrderEvent {
PAY,
SHIP,
COMPLETE
}
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.statemachine.config.EnableStateMachine;
import org.springframework.statemachine.config.StateMachineConfigurerAdapter;
import org.springframework.statemachine.config.builders.StateMachineStateBuilder;
import org.springframework.statemachine.config.builders.StateMachineTransitionBuilder;
import org.springframework.statemachine.state.State;
import org.springframework.statemachine.transition.Transition;
import java.util.EnumSet;
@Configuration // 标识这个类是一个Spring配置类
@EnableStateMachine // 启用Spring State Machine的功能
public class OrderStateMachineConfig extends StateMachineConfigurerAdapter {
// 配置状态机状态
@Override
public void configure(StateMachineStateConfigurer<OrderState, String> states) throws Exception {
states
// 定义CREATED状态
.withStates()
.initial(OrderState.CREATED) // 设置CREATED为初始状态
.state(OrderState.CREATED, createStateBuilder(OrderState.CREATED))
.state(OrderState.PAID, createStateBuilder(OrderState.PAID))
.state(OrderState.SHIPPED, createStateBuilder(OrderState.SHIPPED))
.state(OrderState.COMPLETED, createStateBuilder(OrderState.COMPLETED));
}
// 创建状态构建器,可以添加更多配置(如子状态、进入/退出动作等)
private State<OrderState, String> createStateBuilder(OrderState state) {
return new StateMachineStateBuilder<OrderState, String>(state)
.build();
}
// 配置状态机转换
@Override
public void configure(StateMachineTransitionConfigurer<OrderState, String> transitions) throws Exception {
transitions
.withExternal()
.source(OrderState.CREATED).target(OrderState.PAID).event("PAY")
.and()
.source(OrderState.PAID).target(OrderState.SHIPPED).event("SHIP")
.and()
.source(OrderState.SHIPPED).target(OrderState.COMPLETED).event("COMPLETE");
}
// 创建状态机的Bean
@Bean(name = "orderStateMachine")
public StateMachine<OrderState, String> orderStateMachine(StateMachineFactory<OrderState, String> factory) throws Exception {
return factory.getStateMachine("orderStateMachine");
}
// 可以添加更多配置方法,例如监听器配置、守卫配置等
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.statemachine.state.State;
import org.springframework.statemachine.StateMachine;
import org.springframework.stereotype.Service;
@Service
public class OrderService {
private final StateMachine<OrderState, OrderEvent> orderStateMachine;
@Autowired
public OrderService(StateMachine<OrderState, OrderEvent> orderStateMachine) {
this.orderStateMachine = orderStateMachine;
}
public void createOrder() {
// 假设订单已经创建,现在触发状态机到CREATED状态
// 实际上,这里可能涉及订单的创建逻辑
orderStateMachine.start();
System.out.println("Order created and state machine started in state: " + orderStateMachine.getState().getId());
}
public void payOrder() {
// 发送支付事件,状态机将转移到PAID状态
orderStateMachine.sendEvent(OrderEvent.PAY);
System.out.println("Order paid and state machine is now in state: " + orderStateMachine.getState().getId());
}
public void shipOrder() {
// 发送发货事件,状态机将转移到SHIPPED状态
orderStateMachine.sendEvent(OrderEvent.SHIP);
System.out.println("Order shipped and state machine is now in state: " + orderStateMachine.getState().getId());
}
public void completeOrder() {
// 发送完成事件,状态机将转移到COMPLETED状态
orderStateMachine.sendEvent(OrderEvent.COMPLETE);
System.out.println("Order completed and state machine is now in state: " + orderStateMachine.getState().getId());
}
public State<OrderState> getCurrentState() {
return orderStateMachine.getState();
}
}
类说明:
OrderStateMachineConfig
类是一个Spring配置类,它扩展了StateMachineConfigurerAdapter
来配置订单的状态机。它使用了Spring State Machine
的注解@EnableStateMachine
来启用状态机的功能。
方法详解:
configure(StateMachineStateConfigurer<OrderState, String> states)
:这个方法用于配置状态机的状态。它使用withStates方法定义了订单的所有可能状态,并设置了CREATED为初始状态。createStateBuilder(OrderState state)
:这是一个私有辅助方法,它创建一个状态构建器,并返回配置好的状态对象。你可以在这个方法里添加更多状态的配置,比如子状态、进入/退出动作等。configure(StateMachineTransitionConfigurer<OrderState, String> transitions)
:这个方法用于配置状态机之间的转换(即触发事件后从一个状态转移到另一个状态)。它定义了从CREATED到PAID、从PAID到SHIPPED以及从SHIPPED到COMPLETED的转换事件。orderStateMachine(StateMachineFactory<OrderState, String> factory)
:这个方法是一个Bean方法,它创建了状态机的实例并将其注册到Spring容器中。通过StateMachineFactory,我们创建了一个名为"orderStateMachine"的状态机实例。现在,我们已经配置了状态机并创建了服务来操作它。接下来,你可以在应用的任何部分注入OrderService
,并调用相应的方法来改变订单的状态。
例如,在一个控制器中,你可以这样做:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class OrderController {
private final OrderService orderService;
@Autowired
public OrderController(OrderService orderService) {
this.orderService = orderService;
}
@GetMapping("/create-order")
public String createOrder() {
orderService.createOrder();
return "Order created";
}
@GetMapping("/pay-order")
public String payOrder() {
orderService.payOrder();
return "Order paid";
}
@GetMapping("/ship-order")
public String shipOrder() {
orderService.shipOrder();
return "Order shipped";
}
@GetMapping("/complete-order")
public String completeOrder() {
orderService.completeOrder();
return "Order completed";
}
@GetMapping("/order-status")
public String getOrderStatus() {
State<OrderState> currentState = orderService.getCurrentState();
return "Current order status: " + currentState.getId();
}
在上面的示例代码中,我们定义了一个OrderController,它提供了几个HTTP端点来模拟订单状态的改变和查询当前状态。你可以通过访问这些端点来与状态机交互。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。