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;
-
}
- ?