javascript
Spring基于状态机squirrel-foundation简单使用
squirrel-foundation的一些使用方法在百度上資料還是比較少,我是根據(jù)以下三個大佬寫的文章借鑒的,在這里記錄一下。
1、squirrel-foundation-demo
2、Squirrel使用(中文文檔)
3、squirrel-foundation狀態(tài)機的使用細節(jié)
我在這里直接粘貼代碼,便于自己之后理解。
/**
* 通過Spring創(chuàng)建StateMachineBuilder實例,通過buidler創(chuàng)建狀態(tài)機(單例)
* 創(chuàng)建無類型化狀態(tài)機,簡化狀態(tài)機,防止過多泛化導致代碼不易閱讀(因為不太理解一些高級的使用)
*/
public abstract class AbstractStateMachineEngine <T extends UntypedStateMachine> implements ApplicationContextAware {
private ApplicationContext applicationContext;
protected UntypedStateMachineBuilder stateMachineBuilder = null;
@SuppressWarnings("unchecked")
public AbstractStateMachineEngine() {
//識別泛型參數(shù)
Class<T> genericType = (Class<T>) GenericTypeResolver.resolveTypeArgument(getClass(),
AbstractStateMachineEngine.class);
stateMachineBuilder = StateMachineBuilderFactory.create(genericType, ApplicationContext.class);
}
//注入applicationContext,并在創(chuàng)建StateMachine實例時注入
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
/**
* 可以通過向OrderContext 上下文傳遞一些業(yè)務參數(shù),比如orderId等等
*/
public boolean fire(EOrderEvents event, OrderContext context) {
T stateMachine = stateMachineBuilder.newUntypedStateMachine(
context.geteOrder().getOrderStatus(),
applicationContext);
//由于StateMachine實例不是由Spring容器創(chuàng)建,所以這個過程中無法通過注解方式開啟事務(Spring沒有機會去創(chuàng)建事務代理),因此采用了編程式事務
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);
//這里會返回狀態(tài)機是否出錯,如果出錯可用于通知Controller層,目前只會這樣簡單的操作
return stateMachine.isError();
} catch (Exception ex) {
//用于事務回滾
transactionManager.rollback(status);
return true;
}
}
}
/**
* 該類相當于監(jiān)聽狀態(tài)變化,構(gòu)造一些監(jiān)聽方法實現(xiàn)一些邏輯代碼
* @States 定義狀態(tài)列表,里面可以包含多個狀態(tài)
* @State定義每個狀態(tài),name狀態(tài)名稱,entryStateInit進入狀態(tài)時調(diào)用的方法,exitCallMethod 離開狀態(tài)是調(diào)用的方法,initialState 為true時,為默認狀態(tài)。
* */
@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傳遞的參數(shù)
@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;
//定義構(gòu)造函數(shù)接受ApplicationContext注入([參看New State Machine Instance](http://hekailiang.github.io/squirrel/))
public SubmitOrderStateMachine(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
// 通過applicationContext注入orderService,這樣就可以通過service操作數(shù)據(jù)庫
OrderService = (OrderService) this.applicationContext.getBean("OrderService");
}
//創(chuàng)建訂單,依舊處于待使用狀態(tài)
public void createOrder(OrderStates fromState, OrderStates toState, OrderEvents OrderEvents, OrderContext OrderContext) {
//可以做一些創(chuàng)建訂單等等操作
}
//提交訂單
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) {
}
/**
* 如果實現(xiàn)這個方法,當上面方法執(zhí)行出現(xiàn)錯誤時就會轉(zhuǎn)到這里來執(zhí)行。
* 但是由于自己是菜鳥,并不知道出錯后這里該如何通知到Controller層
* 因此這里并未實現(xiàn),具體的實現(xiàn)方法請參考官網(wǎng)
*/
/*
@Override
protected void afterTransitionCausedException(Object fromState, Object toState, Object event, Object context) {
//super.afterTransitionCausedException(fromState, toState, event, context);
}*/
}
還需要一個類集成AbstractStateMachineEngine,用于調(diào)用fire()方法。該類需要添加@Service注解,以便spring注入
@Service
public class OrderStateMachineEngine extends AbstractStateMachineEngine<SubmitOrderStateMachine>{
}
Controller層使用:
/**
* 這里需要加上try**catch**,以便發(fā)生錯誤可方便執(zhí)行下去
*/
@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));
//向訂單上下文可添加一些邏輯參數(shù),如: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;
//邏輯參數(shù)
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枚舉:
/**
* 訂單狀態(tài)轉(zhuǎn)變事件
* */
public enum OrderEvents {
FOUND, //創(chuàng)建訂單
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枚舉:
/**
* 訂單狀態(tài)
* */
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;
}
/**
* 實現(xiàn)IEnum接口重寫的該方法
* 該方法的作用就是表示返回的值,將要存儲在數(shù)據(jù)庫中
* 和EnumValue注解作用一樣,在字段上EnumValue,就可不需要實現(xiàn)IEnum接口
* */
@Override
public Integer getValue() {
// TODO Auto-generated method stub
return code;
}
總結(jié)
以上是生活随笔為你收集整理的Spring基于状态机squirrel-foundation简单使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c#扫描图片去黑边(扫描仪去黑边)
- 下一篇: squirrel-foundation-