国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

squirrel-foundation狀態(tài)機(jī)的使用細(xì)節(jié)

wmui / 934人閱讀

摘要:狀態(tài)機(jī)的使用細(xì)節(jié)上一篇文章介紹了以及三款狀態(tài)機(jī)引擎的實(shí)現(xiàn)原理,以及我為何選擇作為解決方案。被代理的默認(rèn)實(shí)現(xiàn)為,內(nèi)部描述了狀態(tài)機(jī)實(shí)例創(chuàng)建細(xì)節(jié)包括類型信息等,同時(shí)也包含了的一些全局共享資源包括等。

squirrel-foundation狀態(tài)機(jī)的使用細(xì)節(jié)

date: 2017-06-19 15:50:18

上一篇文章介紹了stateless4j、spring-statemachine以及squirrel-foundation三款狀態(tài)機(jī)引擎的實(shí)現(xiàn)原理,以及我為何選擇squirrel-foundation作為解決方案。本文主要介紹一下項(xiàng)目中如何使用squirrel-foundation的一些細(xì)節(jié)以及如何與spring進(jìn)行集成。在閱讀本文前,建議先閱讀官方的使用手冊(cè)。

生命周期 狀態(tài)機(jī)創(chuàng)建過(guò)程

StateMachine: StateMachine實(shí)例由StateMachineBuilder創(chuàng)建不被共享,對(duì)于使用annotation方式(或fluent api)定義的StateMachine,StateMachine實(shí)例即根據(jù)此定義創(chuàng)建,相應(yīng)的action也由本實(shí)例執(zhí)行,與spring的集成最終要的就是講spring的bean實(shí)例注入給由builder創(chuàng)建的狀態(tài)機(jī)實(shí)例;

StateMachineBuilder: 本質(zhì)上是由StateMachineBuilderFactory創(chuàng)建的動(dòng)態(tài)代理。被代理的StateMachineBuilder默認(rèn)實(shí)現(xiàn)為StateMachineBuilderImpl,內(nèi)部描述了狀態(tài)機(jī)實(shí)例創(chuàng)建細(xì)節(jié)包括State、Event、Context類型信息、constructor等,同時(shí)也包含了StateMachine的一些全局共享資源包括StateConverter、EventConverter、MvelScriptManager等。StateMachineBuilder可被復(fù)用,使用中可被實(shí)現(xiàn)為singleton;

StateMachineBuilderFactory: 為StateMachineBuilder創(chuàng)建的動(dòng)態(tài)代理實(shí)例;

事件處理過(guò)程

狀態(tài)正常遷移
TransitionBegin--(exit->transition->entry)-->TransitionComplete-->TransitionEnd

狀態(tài)遷移異常
TransitionBegin--(exit->transition->entry)-->TransitionException-->TransitionEnd

狀態(tài)遷移事件拒絕
TransitionBegin-->TransitionDeclined-->TransitionEnd

spring集成

從statemachine的生命流程上可以看到,StateMachineBuilder可以單例方式由spring container管理,而stateMachine的instance的生命周期伴隨著請(qǐng)求(或業(yè)務(wù))。
從這兩點(diǎn)出發(fā),集成spring需要完成兩件事:

(1).通過(guò)Spring創(chuàng)建StateMachineBuilder實(shí)例;

(2).業(yè)務(wù)函數(shù)中通過(guò)(1)的StateMachineBuilder實(shí)例創(chuàng)建StateMachine實(shí)例,并向StateMachine暴露SpringApplicationContext;

泛型參數(shù)+覆蓋默認(rèn)構(gòu)造函數(shù)隱藏StateMachineBuilder創(chuàng)建細(xì)節(jié),實(shí)現(xiàn)ApplicationContextAware接口,接受applicationContext注入,并注入給stateMachine實(shí)例。

public abstract class AbstractStateMachineEngine implements ApplicationContextAware {
    protected UntypedStateMachineBuilder stateMachineBuilder = null;
    @SuppressWarnings("unchecked")
    public AbstractStateMachineEngine() {
        //識(shí)別泛型參數(shù)
        Class genericType = (Class)GenericTypeResolver.resolveTypeArgument(getClass(),
            AbstractStateMachineEngine.class);
        stateMachineBuilder = StateMachineBuilderFactory.create(genericType, ApplicationContext.class);
    }
    //注入applicationContext,并在創(chuàng)建StateMachine實(shí)例時(shí)注入
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
    //delegate fire
    public void fire(int rmaId, State initialState, Trigger trigger, StateMachineContext context) {
        T stateMachine = stateMachineBuilder.newUntypedStateMachine(
                            initialState
                            //暫時(shí)開(kāi)啟debug進(jìn)行日志trace
                            StateMachineConfiguration.create().enableDebugMode(true).enableAutoStart(true),
                            //注入applicationContext
                            applicationContext);
        stateMachine.fire(trigger, context);
    }
    ...
}
@Service
class DiscountRefundStateMachineEngine extends AbstractStateMachineEngine {
}
@Service
public class ReturnGoodsStateMachineEngine extends AbstractStateMachineEngine {
}

StateMachine定義,接受SpringContext注入

@StateMachineParameters(stateType = State.class, eventType = Trigger.class,
    //StateMachineContext 自定義上下文,用來(lái)傳遞數(shù)據(jù)
    contextType = StateMachineContext.class)
@States({
    @State(name = "PENDING", initialState = true),
    @State(name = "CONFIRMING"),
    @State(name = "REJECTED"),
    @State(name = "REFUND_APPROVING"),
    @State(name = "REFUND_APPROVED"),
    @State(name = "REFUND_FINISHED")
})
@Transitions({
    @Transit(from = "PENDING", to = "CONFIRMING", on = "APPLY_CONFIRM",
        callMethod = "doSomething"),
    @Transit(from = "CONFIRMING", to = "REJECTED", on = "REJECT"),
    @Transit(from = "CONFIRMING", to = "REFUND_APPROVING", on = "APPLY_APPROVED"),
    @Transit(from = "REFUND_APPROVING", to = "REFUND_APPROVED", on = "REFUND_APPROVED"),
    @Transit(from = "REFUND_APPROVED", to = "REFUND_FINISHED", on = "REFUND_FINISH_CONFIRM")
})
public class DiscountRefundStateMachine extends AbstractUntypedStateMachine {
    protected ApplicationContext applicationContext;
    //定義構(gòu)造函數(shù)接受ApplicationContext注入([參看New State Machine Instance](http://hekailiang.github.io/squirrel/))
    public DiscountRefundStateMachine(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }
    public void doSomething(State fromState, State toState, Trigger event,
                         StateMachineContext stateMachineContext) {
         DemoBean demoBean = this.applicationContext.get("demoBean");
         //do something
    }
    ...
}
狀態(tài)持久化

從StateMachine的事件響應(yīng)流程中可以看到,TransitionBegin--(exit->transition->entry)-->TransitionComplete-->TransitionEnd,在TransitionComplete發(fā)生一個(gè)狀態(tài)已從source遷移到了target狀態(tài),所以我選擇了在這個(gè)時(shí)間點(diǎn)進(jìn)行了狀態(tài)的持久化(沒(méi)有選擇TransitionEnd做持久化,因?yàn)槟承﹫?chǎng)景在持久化完成后還會(huì)存在一些外部動(dòng)作的觸發(fā),例如通知第三方系統(tǒng)當(dāng)前狀態(tài)已完成變更)。

public class DiscountRefundStateMachine extends AbstractUntypedStateMachine {
    ..
    @Override
    protected void afterTransitionCompleted(Object fromState, Object toState, Object event, Object context) {
        if (context instanceof StateMachineContext && toState instanceof State) {
            StateMachineContext stateMachineContext = (StateMachineContext)context;
            //從上下文中獲取需要持久化的數(shù)據(jù),例如訂單ID等
            Rma rma = stateMachineContext.get(MessageKeyEnum.RMA);
            //持久化
            rma.setStatus((State)toState);
            this.applicationContext.get("rmaRepository").updateRma(rma);
        } else {
            throw new Exception("type not support, context expect " + StateMachineContext.class.getSimpleName() + ", actually "
                    + context.getClass().getSimpleName() + ", state expect " + State.class.getSimpleName()
                    + ", actually "
                    + toState.getClass().getSimpleName());
        }
    }
}
分布式鎖+事務(wù)

由于StateMachine實(shí)例不是由Spring容器創(chuàng)建,所以這個(gè)過(guò)程中無(wú)法通過(guò)注解方式開(kāi)啟事務(wù)(Spring沒(méi)有機(jī)會(huì)去創(chuàng)建事務(wù)代理),我采用了編程式事務(wù),在AbstractStateMachineEngine的fire函數(shù)中隱式的實(shí)現(xiàn)。
AbstractStateMachineEngine#fire

public abstract class AbstractStateMachineEngine implements ApplicationContextAware {
    ...
    public void fire(int rmaId, State initialState, Trigger trigger, StateMachineContext context) {
        JedisLock jedisLock = jedisLockFactory.buildLock(rmaId);
        //爭(zhēng)用分布式鎖
        if (jedisLock.tryLock()) {
            try {
                T stateMachine = stateMachineBuilder.newUntypedStateMachine(
                                    initialState
                                    //暫時(shí)開(kāi)啟debug進(jìn)行日志trace
                                    StateMachineConfiguration.create().enableDebugMode(true).enableAutoStart(true),
                                    //注入applicationContext
                                    applicationContext);
                DataSourceTransactionManager transactionManager = applicationContext.get("transactionManager")
                DefaultTransactionDefinition def = new DefaultTransactionDefinition();
                def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
                TransactionStatus status = transactionManager.getTransaction(def);
                try {
                    stateMachine.fire(trigger, context)
                    transactionManager.commit(status);
                } catch (Exception ex) {
                    transactionManager.rollback(status);
                    throw ex;
                }
            } finally {
                jedisLock.release();
            }
        } 
        ...
    }
}
使用graphviz生成狀態(tài)拓?fù)鋱D

squirrel statemachine提供了DotVisitor、SCXMLVisitor兩種實(shí)現(xiàn)方式用于生成狀態(tài)機(jī)描述文件,項(xiàng)目里我選擇了graphviz用來(lái)做狀態(tài)拓?fù)?br>graphviz gui工具下載
PS:由于squirrel默認(rèn)的DotVisitorImpl對(duì)帶中文描述屬性的State/Event枚舉不友好,我在原有代碼上做了一些調(diào)整,有類似需求的可以看這里

更多文章請(qǐng)?jiān)L問(wèn)我的博客
轉(zhuǎn)載請(qǐng)注明出處

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/67214.html

相關(guān)文章

  • 狀態(tài)機(jī)引擎選型

    摘要:狀態(tài)機(jī)引擎選型概念有限狀態(tài)機(jī)是一種用來(lái)進(jìn)行對(duì)象行為建模的工具,其作用主要是描述對(duì)象在它的生命周期內(nèi)所經(jīng)歷的狀態(tài)序列,以及如何響應(yīng)來(lái)自外界的各種事件。狀態(tài)機(jī)的要素狀態(tài)機(jī)可歸納為個(gè)要素,即現(xiàn)態(tài)條件動(dòng)作次態(tài)。 狀態(tài)機(jī)引擎選型 date: 2017-06-19 15:50:18 概念 有限狀態(tài)機(jī)是一種用來(lái)進(jìn)行對(duì)象行為建模的工具,其作用主要是描述對(duì)象在它的生命周期內(nèi)所經(jīng)歷的狀態(tài)序列,以及如何響應(yīng)...

    caige 評(píng)論0 收藏0
  • 有限狀態(tài)機(jī)學(xué)習(xí)

    摘要:狀態(tài)機(jī)有三個(gè)特征狀態(tài)總數(shù)是有限的。由于有限狀態(tài)機(jī)的這些特征,我們可以把狀態(tài)轉(zhuǎn)移的過(guò)程做成類似這樣的狀態(tài)轉(zhuǎn)移表。 有限狀態(tài)機(jī)是什么 有限狀態(tài)機(jī)(英語(yǔ):finite-state machine,縮寫:FSM)又稱有限狀態(tài)自動(dòng)機(jī),簡(jiǎn)稱狀態(tài)機(jī),是表示有限個(gè)狀態(tài)(State)以及在這些狀態(tài)之間的轉(zhuǎn)移(Transition)和動(dòng)作(Action)等行為的數(shù)學(xué)模型。 狀態(tài)機(jī)有三個(gè)特征: 狀態(tài)(St...

    xiao7cn 評(píng)論0 收藏0
  • 有限狀態(tài)機(jī)學(xué)習(xí)

    摘要:狀態(tài)機(jī)有三個(gè)特征狀態(tài)總數(shù)是有限的。由于有限狀態(tài)機(jī)的這些特征,我們可以把狀態(tài)轉(zhuǎn)移的過(guò)程做成類似這樣的狀態(tài)轉(zhuǎn)移表。 有限狀態(tài)機(jī)是什么 有限狀態(tài)機(jī)(英語(yǔ):finite-state machine,縮寫:FSM)又稱有限狀態(tài)自動(dòng)機(jī),簡(jiǎn)稱狀態(tài)機(jī),是表示有限個(gè)狀態(tài)(State)以及在這些狀態(tài)之間的轉(zhuǎn)移(Transition)和動(dòng)作(Action)等行為的數(shù)學(xué)模型。 狀態(tài)機(jī)有三個(gè)特征: 狀態(tài)(St...

    bbbbbb 評(píng)論0 收藏0
  • “數(shù)學(xué)之美”系列十:有限狀態(tài)機(jī)和地址識(shí)別

    地址的識(shí)別和分析是本地搜索必不可少的技術(shù),盡管有許多識(shí)別和分析地址的方法,最有效的是有限狀態(tài)機(jī)。一個(gè)有限狀態(tài)機(jī)是一個(gè)特殊的有向圖(參見(jiàn)有關(guān)圖論的系列),它包括一些狀態(tài)(節(jié)點(diǎn))和連接這些狀態(tài)的有向弧。下圖是一個(gè)識(shí)別中國(guó)地址的有限狀態(tài)機(jī)的簡(jiǎn)單的例子。每一個(gè)有限狀態(tài)機(jī)都有一個(gè)啟始狀態(tài)和一個(gè)終止?fàn)顟B(tài)和若干中間狀態(tài)。每一條弧上帶有從一個(gè)狀態(tài)進(jìn)入下一個(gè)狀態(tài)的條件。比如,在上圖中,當(dāng)前的狀態(tài)是省,如果遇到一個(gè)詞...

    libxd 評(píng)論0 收藏0
  • 云計(jì)算戰(zhàn)爭(zhēng):OpenStack vs. VMware

    摘要:和的云計(jì)算功能特點(diǎn)對(duì)比正是這個(gè)戰(zhàn)爭(zhēng)或者說(shuō)趨勢(shì)的一個(gè)生動(dòng)寫照。在設(shè)計(jì)方面稍占優(yōu)勢(shì),這源于它優(yōu)秀的文檔資料以及便捷易用的部署和管理接口。總而言之,目前調(diào)度器將只會(huì)對(duì)部署虛擬機(jī)環(huán)節(jié)有影響。 在云計(jì)算生態(tài)系統(tǒng)中,有兩種類型的用戶需要使用云計(jì)算資源:傳統(tǒng)型(Traditional IT applications)和在互聯(lián)網(wǎng)大潮下逐漸崛起云計(jì)算應(yīng)用型(Cloud-aware applications)。...

    李濤 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<