介绍
Spring状态机为程序开发员提供了传统状态机和Spring应用程序使用,有以下特性:
* 易于使用的状态机的用例
* 层次的状态机结构缓解复杂状态机的配置
* 状态机提供更复杂的配置状态
* 使用触发器、转移、警卫以及动作
* 类型安全的配置适配器
* 状态机的事件监听器
* IOC将状态机和bean整合
名词解释
- State Machine
- 将状态结合、转移、事件整合到一起
- State
- 一个不变的状态模型
- 主要由一个事件修改实体的状态
- Extended State
- 扩展状态是一组特殊的变量保存在一个状态机来减少所需的数据量。
- Transition
- 源状态和目标状态之间的关系,它可能是复合过度的一部分,将状态机配置从一个状态到另一个地方,响应状态机的一个特定类型的事件的发生。
- Event
- 一个实体发送一个状态驱动各个状态的变化
- Initial State
- 状态机特殊的开始状态. 初始状态标记在一个状态或者一个区域上. 一个状态的多个区域都可能回到初始状态
- End State
- 一种最终状态,一种特殊的状态表示完成封闭区域,如果封闭区域直接包含在一个状态机状态机和其他地区也完成了,然后它意味着整个状态机完成。
- History State
- 伪状态可以记住它的最后活动的状态, 存在两种类型历史状态.
- Choice State
- 允许选择基础即过度, 事件标题或扩展状态变量.
- Fork State
- 状态赋予一个控制进入一个地区.
- Join State
- 状态赋予一个退出控制区域.
- Region
- 组合状态或者状态机。它包含状态和转换.
- Guard
- 用一个布尔表达式来表示扩展状态变量的价值动态评估和事件参数. 守卫条件影响的行为状态机通过启用操作或转换,只有当他们评估为TRUE并评估为FALSE时禁用它们.
- Action
- 行动是一种行为的触发过渡期间执行.
使用场景
- 如果你的项目很好的使用状态机:
- 应用程序的结构可以表示成状态的一部分。
- 你希望复杂的逻辑分割成更小的可管理的任务。
- 应用程序已经遭受异步的并发性问题。
- 如果你准备实现一个状态机:
- 使用布尔标记和枚举模型的情况
- 对于某些应用程序生命周期的一部分的有效变量
- 遍历if/else结构设置特定标示和枚举
例子
定义枚举和实现
/**
* 状态
*/
public enum Status{
START,
CANCEL,
ENE;
}
/**
* 事件
*/
public enum Events {
SAVE;
}
状态机配置
@Configuration
@EnableStateMachine(name = "orderStateMachine")
public class TestStateMachineConfig extends EnumStateMachineConfigurerAdapter<Status, Events> {
@Resource
private SaveAction saveAction;
@Override
public void configure(StateMachineStateConfigurer<Status, Events> states)
throws Exception {
states
.withStates()
.initial(Status.START)
.states(EnumSet.allOf(Status.class));
}
@Override
public void configure(StateMachineTransitionConfigurer<Status, Events> transitions)
throws Exception {
transitions
.withExternal()
.source(Status.START).target(Status.END)
.event(Events.SAVE).action(saveAction)
;
}
@Override
public void configure(StateMachineConfigurationConfigurer<Status, Events> config)
throws Exception {
config
.withConfiguration().autoStartup(true)
.listener(listener());
}
@Bean
public StateMachineListener<Status, Events> listener() {
return new StateMachineListenerAdapter<Status, Events>() {
@Override
public void transition(Transition<Status, Events> transition) {
if (transition.getTarget().getId() == Status.START) {
System.out.println("订单创建,待支付");
return;
}
}
};
}
}
定义Action
@Component
public class SaveAction implements Action<Status, Events>{
@Resource
private OrderInfoService orderInfoService;
@Override
public void execute(StateContext<Status, Events> context) {
Order order = (Order) context.getMessageHeader(OrderStatusContextKey.ORDER_ENTITY_KEY);
orderInfoService.save(order);
}
}
状态机管理类
@Component
public class DefaultStateMachineManager implements InitializingBean, ApplicationContextAware {
private static final String ORDER_STATE_MACHINE_CONFIG = "orderStateMachine";
private ApplicationContext applicationContext;
private StateMachine<Status, Events> orderStateMachine;
@Override
public void afterPropertiesSet() throws Exception {
orderStateMachine = applicationContext.getBean(ORDER_STATE_MACHINE_CONFIG, StateMachine.class);
}
@Override
public StateMachine<OrderStatus, Events> getOrderStateMachine() {
return orderStateMachine;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
业务层
@Service
public class OrderBizImpl {
@Resource
private StateMachineManager stateMachineManager;
@Override
public void save(Order order) {
if (order == null) {
return;
}
StateMachine<Status, Events> orderStateMachine = stateMachineManager.getOrderStateMachine();
Message<Events> message = MessageBuilder
.withPayload(Events.SAVE)
.setHeader(ORDER_ENTITY_KEY, order)
.build();
orderStateMachine.sendEvent(message);
}
}
网友评论