squirrel-foundation的一些使用方法在百度上资料还是比较少,我是根据以下三个大佬写的文章借鉴的,在这里记录一下。
1、squirrel-foundation-demo
2、Squirrel使用(中文文档)
3、squirrel-foundation状态机的使用细节
我在这里直接粘贴代码,便于自己之后理解。
-
/** -
* 通过Spring创建StateMachineBuilder实例,通过buidler创建状态机(单例) -
* 创建无类型化状态机,简化状态机,防止过多泛化导致代码不易阅读(因为不太理解一些高级的使用) -
*/ -
public abstract 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; -
} -
/** -
* 可以通过向OrderContext 上下文传递一些业务参数,比如orderId等等 -
*/ -
public boolean fire(EOrderEvents event, OrderContext context) { -
T stateMachine = stateMachineBuilder.newUntypedStateMachine( -
context.geteOrder().getOrderStatus(), -
applicationContext); -
//由于StateMachine实例不是由Spring容器创建,所以这个过程中无法通过注解方式开启事务(Spring没有机会去创建事务代理),因此采用了编程式事务 -
DataSourceTransactionManager transactionManager = (DataSourceTransactionManager)applicationContext.getBean("transactionManager"); -
DefaultTransactionDefinition def = new DefaultTransactionDefinition(); -
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); -
TransactionStatus status = transactionManager.getTransaction(def); -
try { -
stateMachine.fire(event, context); -
transactionManager.commit(status); -
//这里会返回状态机是否出错,如果出错可用于通知Controller层,目前只会这样简单的操作 -
return stateMachine.isError(); -
} catch (Exception ex) { -
//用于事务回滚 -
transactionManager.rollback(status); -
return true; -
} -
} -
}
-
/** -
* 该类相当于监听状态变化,构造一些监听方法实现一些逻辑代码 -
* @States 定义状态列表,里面可以包含多个状态 -
* @State定义每个状态,name状态名称,entryStateInit进入状态时调用的方法,exitCallMethod 离开状态是调用的方法,initialState 为true时,为默认状态。 -
* */ -
@States({ -
@State(name = "UNFOUND", entryCallMethod = "entryStateInit", exitCallMethod = "exitStateInit", initialState = true), -
@State(name = "USING", entryCallMethod = "entryStateWaitPay", exitCallMethod = "exitStateWaitPay"), -
@State(name = "COMPLETE", entryCallMethod = "entryStateWaitSend", exitCallMethod = "exitStateWaitSend"), -
@State(name = "REFUND", entryCallMethod = "entryStatePartSend", exitCallMethod = "exitStatePartSend"), -
@State(name = "NOUSE", entryCallMethod = "entryStatePartSend", exitCallMethod = "exitStatePartSend") -
}) -
@Transitions({ -
@Transit(from = "UNFOUND", to = "UNFOUND", on = "FOUND", callMethod = "createOrder"), -
@Transit(from = "UNFOUND", to = "USING", on = "SAOMA", callMethod = "submitOrder"), -
@Transit(from = "USING", to = "COMPLETE", on = "PAY", callMethod = "pay"), -
@Transit(from = "USING", to = "REFUND", on = "USING_REFUNDING", callMethod = "usingRefund"), -
@Transit(from = "COMPLETE", to = "REFUND", on = "COM_REFUNDING", callMethod = "comRefund") -
}) -
//该地方向AbstractStateMachine传递的参数 -
@StateMachineParameters(stateType = OrderStates.class, eventType = OrderEvents.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,这样就可以通过service操作数据库 -
OrderService = (OrderService) this.applicationContext.getBean("OrderService"); -
} -
//创建订单,依旧处于待使用状态 -
public void createOrder(OrderStates fromState, OrderStates toState, OrderEvents OrderEvents, OrderContext OrderContext) { -
//可以做一些创建订单等等操作 -
} -
//提交订单 -
public void submitOrder(OrderStates fromState, OrderStates toState, OrderEvents OrderEvents, OrderContext OrderContext) { -
} -
//支付订单 -
public void pay(OrderStates fromState, OrderStates toState, OrderEvents OrderEvents, OrderContext OrderContext) { -
} -
public void usingRefund(OrderStates fromState, OrderStates toState, OrderEvents OrderEvents, OrderContext OrderContext) { -
} -
public void comRefund(OrderStates fromState, OrderStates toState, OrderEvents OrderEvents, OrderContext OrderContext) { -
} -
/** -
* 如果实现这个方法,当上面方法执行出现错误时就会转到这里来执行。 -
* 但是由于自己是菜鸟,并不知道出错后这里该如何通知到Controller层 -
* 因此这里并未实现,具体的实现方法请参考官网 -
*/ -
/* -
@Override -
protected void afterTransitionCausedException(Object fromState, Object toState, Object event, Object context) { -
//super.afterTransitionCausedException(fromState, toState, event, context); -
}*/ -
}
还需要一个类集成AbstractStateMachineEngine,用于调用fire()方法。该类需要添加@Service注解,以便spring注入
-
@Service -
public class OrderStateMachineEngine extends AbstractStateMachineEngine<SubmitOrderStateMachine>{ -
}
Controller层使用:
-
/** -
* 这里需要加上try**catch**,以便发生错误可方便执行下去 -
*/ -
@RequestMapping(value="/modOrderStatus",method = {RequestMethod.POST}) -
@ResponseBody -
public ResultEntity<Order> modOrderStatus(@RequestParam("event") String event,int code,Long orderId){ -
ResultEntity<Order> resultEntity = new ResultEntity<Order>(); -
try { -
Order Order = new Order(); -
Order.setOrderStatus(OrderStates.getState(code)); -
//向订单上下文可添加一些逻辑参数,如:orderId -
OrderContext OrderContext = new OrderContext(Order, orderId); -
if(!orderStateMachineEngine.fire(OrderEvents.getEvent(event), OrderContext)) { -
resultEntity.setCode(1); -
resultEntity.setMessage("成功!"); -
}else { -
resultEntity.setCode(0); -
resultEntity.setMessage("更新失败,请重新尝试!"); -
} -
return resultEntity; -
} catch (Exception e) { -
e.printStackTrace(); -
log.error(e); -
resultEntity.setCode(0); -
resultEntity.setMessage("更新失败,请重新尝试!"); -
return resultEntity; -
} -
}
OrderContext类:
-
/** -
* 订单上下文 -
* */ -
public class OrderContext { -
public OrderContext(Order eOrder,Long orderId) { -
this.Order = Order; -
this.orderId = orderId; -
} -
public OrderContext() { -
} -
private Order Order; -
//逻辑参数 -
private Long orderId; -
public Order getOrder() { -
return Order; -
} -
public void seteOrder(Order Order) { -
this.Order = Order; -
} -
public Long getOrderId() { -
return orderId; -
} -
public void setOrderId(Long orderId) { -
this.orderId = orderId; -
} -
}
OrderEvents枚举:
-
/** -
* 订单状态转变事件 -
* */ -
public enum OrderEvents { -
FOUND, //创建订单 -
SAOMA, //提交订单 -
PAY, //付款 -
USING_REFUNDING, -
COM_REFUNDING; -
public static OrderEvents getEvent(String event) { -
for (OrderEvents orderEvent : OrderEvents.values()) { -
if (orderEvent.name().equals(event)) { -
return orderEvent; -
} -
} -
return null; -
} -
}
OrderStatus枚举:
-
/** -
* 订单状态 -
* */ -
public enum OrderStates implements IEnum<Integer>{ -
UNFOUND(1,"待使用"), -
USING(2,"正使用"), -
COMPLETE(3,"已完成"), -
REFUND(4,"退款"), -
NOUSE(5,"放弃订单"); -
private String desc; -
private int code; -
private OrderStates(int code,String desc) { -
this.code = code; -
this.desc = desc; -
} -
public String getDesc() { -
return desc; -
} -
public void setDesc(String desc) { -
this.desc = desc; -
} -
public int getCode() { -
return code; -
} -
public void setCode(int code) { -
this.code = code; -
} -
public static OrderStates getState(int code) { -
for (OrderStates orderState : OrderStates.values()) { -
if (orderState.ordinal()+1 == code) { -
return orderState; -
} -
} -
return null; -
} -
/** -
* 实现IEnum接口重写的该方法 -
* 该方法的作用就是表示返回的值,将要存储在数据库中 -
* 和EnumValue注解作用一样,在字段上EnumValue,就可不需要实现IEnum接口 -
* */ -
@Override -
public Integer getValue() { -
// TODO Auto-generated method stub -
return code; -
}