一个简单的squirrel-foundation-demo
利用状态机模拟一个订单的支付过程。
squirrel-foundation没有任何严重的依赖关系,因此基本上它应该是高度可嵌入的。squirrel-foundation没有整合spring框架,所以首先要用spring集成squirrel-foundation。
spring集成squirrel-foundation
(1).通过Spring创建StateMachineBuilder实例(单例);
(2).业务函数中通过(1)的StateMachineBuilder实例创建StateMachine实例,并向StateMachine暴露SpringApplicationContext,以便于StateMachine通过ApplicationContext获取数据层的对象。
public class AbstractStateMachineEngine <T extends UntypedStateMachine> implements ApplicationContextAware {
private ApplicationContext applicationContext;
protected UntypedStateMachineBuilder stateMachineBuilder = null;
@SuppressWarnings("unchecked")
public AbstractStateMachineEngine() {
//识别泛型参数
Class<T> genericType = (Class<T>) GenericTypeResolver.resolveTypeArgument(getClass(),
AbstractStateMachineEngine.class);
stateMachineBuilder = StateMachineBuilderFactory.create(genericType, ApplicationContext.class);
}
//注入applicationContext,并在创建StateMachine实例时注入
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
public void fire(OrderEvent event, OrderContext context) {
T stateMachine = stateMachineBuilder.newUntypedStateMachine(
context.orderDTO.getState(),
//暂时开启debug进行日志trace
StateMachineConfiguration.create().enableDebugMode(true).enableAutoStart(true),
//注入applicationContext
applicationContext);
stateMachine.fire(event, context);
}
}
继承AbstractStateMachineEngine,并加入@Service注解,便可以在项目中注入。(单例)
@Service
public class OrderStateMachineEngine extends AbstractStateMachineEngine<SubmitOrderStateMachine>{
}
基于注解的方式定义状态机
@States 定义状态列表,里面可以包含多个状态
@State定义每个状态,name状态名称,entryStateInit进入状态时调用的方法,exitCallMethod 离开状态是调用的方法,initialState 为true时,为默认状态。
@States({
@State(name = "INIT", entryCallMethod = "entryStateInit", exitCallMethod = "exitStateInit", initialState = true),
@State(name = "WAIT_PAY", entryCallMethod = "entryStateWaitPay", exitCallMethod = "exitStateWaitPay"),
@State(name = "WAIT_SEND", entryCallMethod = "entryStateWaitSend", exitCallMethod = "exitStateWaitSend"),
@State(name = "PART_SEND", entryCallMethod = "entryStatePartSend", exitCallMethod = "exitStatePartSend"),
@State(name = "WAIT_RECEIVE", entryCallMethod = "entryStateWaitReceive", exitCallMethod = "exitStateWaitReceive"),
@State(name = "COMPLETE", entryCallMethod = "entryStateComplete", exitCallMethod = "exitStateComplete")
})
@Transitions({
@Transit(from = "INIT", to = "WAIT_PAY", on = "SUBMIT_ORDER", callMethod = "submitOrder"),
@Transit(from = "WAIT_PAY", to = "WAIT_SEND", on = "PAY", callMethod = "pay"),
@Transit(from = "WAIT_SEND", to = "PART_SEND", on = "PART_SEND", callMethod = "partSend"),
@Transit(from = "PART_SEND", to = "WAIT_RECEIVE", on = "SEND", callMethod = "send"),
@Transit(from = "WAIT_RECEIVE", to = "COMPLETE", on = "COMPLETE", callMethod = "complete")
})
@StateMachineParameters(stateType = OrderState.class, eventType = OrderEvent.class, contextType = OrderContext.class)
public class SubmitOrderStateMachine extends AbstractStateMachine<UntypedStateMachine, Object, Object, Object> implements UntypedStateMachine {
private OrderService orderService;
protected ApplicationContext applicationContext;
//定义构造函数接受ApplicationContext注入([参看New State Machine Instance](http://hekailiang.github.io/squirrel/))
public SubmitOrderStateMachine(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
// 通过applicationContext注入orderService
orderService = (OrderService) this.applicationContext.getBean("orderService");
}
public void submitOrder(OrderState fromState, OrderState toState, OrderEvent orderEvent, OrderContext orderContext) {
orderService.submitOrder(toState);
}
public void pay(OrderState fromState, OrderState toState, OrderEvent orderEvent, OrderContext orderContext) {
System.out.println("pay");
}
public void partSend(OrderState fromState, OrderState toState, OrderEvent orderEvent, OrderContext orderContext) {
System.out.println("partSend");
}
public void send(OrderState fromState, OrderState toState, OrderEvent orderEvent, OrderContext orderContext) {
System.out.println("send");
}
public void complete(OrderState fromState, OrderState toState, OrderEvent orderEvent, OrderContext orderContext) {
System.out.println("complete");
}
public void entryStateInit(OrderState fromState, OrderState toState, OrderEvent orderEvent, OrderContext orderContext) {
System.out.println("entryStateInit");
}
public void exitStateInit(OrderState fromState, OrderState toState, OrderEvent orderEvent, OrderContext orderContext) {
System.out.println("exitStateInit");
}
public void entryStateWaitPay(OrderState fromState, OrderState toState, OrderEvent orderEvent, OrderContext orderContext) {
System.out.println("entryStateWaitPay");
}
public void exitStateWaitPay(OrderState fromState, OrderState toState, OrderEvent orderEvent, OrderContext orderContext) {
System.out.println("exitStateWaitPay");
}
public void entryStateWaitSend(OrderState fromState, OrderState toState, OrderEvent orderEvent, OrderContext orderContext) {
System.out.println("entryStateWaitSend");
}
public void exitStateWaitSend(OrderState fromState, OrderState toState, OrderEvent orderEvent, OrderContext orderContext) {
System.out.println("exitStateWaitSend");
}
public void entryStatePartSend(OrderState fromState, OrderState toState, OrderEvent orderEvent, OrderContext orderContext) {
System.out.println("entryStatePartSend");
}
public void exitStatePartSend(OrderState fromState, OrderState toState, OrderEvent orderEvent, OrderContext orderContext) {
System.out.println("exitStatePartSend");
}
public void entryStateWaitReceive(OrderState fromState, OrderState toState, OrderEvent orderEvent, OrderContext orderContext) {
System.out.println("entryStateWaitReceive");
}
public void exitStateWaitReceive(OrderState fromState, OrderState toState, OrderEvent orderEvent, OrderContext orderContext) {
System.out.println("exitStateWaitReceive");
}
public void entryStateComplete(OrderState fromState, OrderState toState, OrderEvent orderEvent, OrderContext orderContext) {
System.out.println("entryStateComplete");
}
public void exitStateComplete(OrderState fromState, OrderState toState, OrderEvent orderEvent, OrderContext orderContext) {
System.out.println("exitStateComplete");
}
}
Service的实现,更新订单状态
@Service
public class OrderService {
@Autowired
OrderDTOMapper orderDTOMapper;
public int submitOrder(OrderState state) {
OrderDTO orderDTO = new OrderDTO();
orderDTO.setState(state);
orderDTOMapper.insert(orderDTO);
return 1;
}
}
mapper
@Mapper
public interface OrderDTOMapper {
int insert(OrderDTO orderDTO);
}
Controller类测试
注入OrderStateMachineEngine ,初始化状态为INIT,通过OrderStateMachineEngine 触发SUBMIT_ORDER事件,发生状态变化,并将转换后的状态插入数据库。
@RestController
@RequestMapping(value = "/order/")
public class OrderController {
// 注入状态机
@Autowired
OrderStateMachineEngine orderStateMachineEngine;
@RequestMapping("/test")
public void test(){
OrderDTO orderDTO = new OrderDTO(OrderState.INIT);
OrderContext orderContext = new OrderContext(orderDTO);
orderStateMachineEngine.fire(OrderEvent.SUBMIT_ORDER,orderContext);
}
}
以下是所用到的实体类定义和状态及事件
订单的实体
public class OrderDTO {
private Integer id;
private OrderState state;
private Date createTime;
private Date updateTime;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public OrderState getState() {
return state;
}
public void setState(OrderState state) {
this.state = state;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
@Override
public String toString() {
return "OrderDTO{" +
"id=" + id +
", state='" + state + '\'' +
", createTime=" + createTime +
", updateTime=" + updateTime +
'}';
}
public OrderDTO(OrderState state) {
this.state = state;
}
public OrderDTO() {
}
}
定义订单的状态
public enum OrderState {
INIT,
WAIT_PAY,
WAIT_SEND,
PART_SEND,
WAIT_RECEIVE,
COMPLETE,
CANCELED;
public static OrderState getState(String state) {
for (OrderState orderState : OrderState.values()) {
if (orderState.name().equalsIgnoreCase(state)) {
return orderState;
}
}
return null;
}
}
定义订单的事件
public enum OrderEvent {
SUBMIT_ORDER,
PAY,
PART_SEND,
SEND,
COMPLETE
}
定义上下文
public class OrderContext {
public OrderContext(OrderDTO orderDTO) {
this.orderDTO = orderDTO;
}
public OrderContext() {
}
public OrderDTO orderDTO;
}