在 Spring 框架中,使用 Spring State Machine (SSM) 可以优雅地替代复杂的 if-else 状态判断逻辑。以下是完整实现方案:
1. 添加依赖
<dependency>
<groupId>org.springframework.statemachine</groupId>
<artifactId>spring-statemachine-starter</artifactId>
<version>3.2.0</version> <!-- 使用最新版本 -->
</dependency>
2. 定义状态和事件枚举
public enum OrderStates {
INIT, // 初始状态
WAITING_PAY, // 待支付
PAID, // 已支付
DELIVERED, // 已发货
RECEIVED, // 已收货
CANCELLED // 已取消
}
public enum OrderEvents {
PAY, // 支付事件
DELIVER, // 发货事件
RECEIVE, // 收货事件
CANCEL_PAYMENT, // 取消支付
CANCEL_ORDER // 取消订单
}
3. 配置状态机
@Configuration
@EnableStateMachine
public class StateMachineConfig
extends EnumStateMachineConfigurerAdapter<OrderStates, OrderEvents> {
@Override
public void configure(StateMachineStateConfigurer<OrderStates, OrderEvents> states)
throws Exception {
states.withStates()
.initial(OrderStates.INIT)
.states(EnumSet.allOf(OrderStates.class))
.end(OrderStates.RECEIVED) // 终态:已收货
.end(OrderStates.CANCELLED); // 终态:已取消
}
@Override
public void configure(StateMachineTransitionConfigurer<OrderStates, OrderEvents> transitions)
throws Exception {
transitions
// 支付事件:从 INIT -> WAITING_PAY
.withExternal()
.source(OrderStates.INIT)
.target(OrderStates.WAITING_PAY)
.event(OrderEvents.PAY)
.and()
// 发货事件:从 PAID -> DELIVERED
.withExternal()
.source(OrderStates.PAID)
.target(OrderStates.DELIVERED)
.event(OrderEvents.DELIVER)
.and()
// 收货事件:从 DELIVERED -> RECEIVED
.withExternal()
.source(OrderStates.DELIVERED)
.target(OrderStates.RECEIVED)
.event(OrderEvents.RECEIVE)
.and()
// 取消支付:从 WAITING_PAY -> CANCELLED
.withExternal()
.source(OrderStates.WAITING_PAY)
.target(OrderStates.CANCELLED)
.event(OrderEvents.CANCEL_PAYMENT)
.and()
// 取消订单:从 INIT -> CANCELLED
.withExternal()
.source(OrderStates.INIT)
.target(OrderStates.CANCELLED)
.event(OrderEvents.CANCEL_ORDER);
}
}
4. 添加状态监听器(处理业务逻辑)
@Component
public class OrderStateListener
extends StateMachineListenerAdapter<OrderStates, OrderEvents> {
@Override
public void transition(Transition<OrderStates, OrderEvents> transition) {
// 状态变化时触发业务逻辑
if (transition.getTarget().getId() == OrderStates.PAID) {
System.out.println("订单已支付,执行库存扣减");
} else if (transition.getTarget().getId() == OrderStates.CANCELLED) {
System.out.println("订单取消,执行退款逻辑");
}
}
}
5. 使用状态机执行业务
@Service
public class OrderService {
@Autowired
private StateMachine<OrderStates, OrderEvents> stateMachine;
public void payOrder() {
// 发送支付事件
stateMachine.sendEvent(OrderEvents.PAY);
}
public void cancelOrder() {
// 发送取消事件
stateMachine.sendEvent(OrderEvents.CANCEL_ORDER);
}
}
6. 测试代码
@SpringBootTest
public class OrderTest {
@Autowired
private OrderService orderService;
@Test
public void testOrderFlow() {
orderService.payOrder(); // 触发支付:INIT -> WAITING_PAY
orderService.cancelOrder(); // 触发取消:WAITING_PAY -> CANCELLED
}
}
优势总结
- 消除复杂 if-else:状态转移由配置定义,业务代码无分支判断
- 集中管理状态逻辑:所有状态流转规则在配置类一目了然
- 高扩展性:新增状态只需修改枚举和配置,无需改动业务代码
- 强约束性:非法状态转移会被框架自动拒绝(如从未支付直接发货)
- 可视化支持:可通过
stateMachine.getStates()调试状态树
关键点:将业务状态的变化抽象为 状态(State) 和 事件(Event),通过状态机驱动流程,彻底告别 if-else 地狱。

浙公网安备 33010602011771号