spring statemachine-復(fù)雜狀態(tài)機(jī)的實(shí)現(xiàn)

1细睡、講講復(fù)雜流程的需求

除了上面文章里面提到的一根筋狀態(tài)機(jī)流程,實(shí)際的企業(yè)應(yīng)用中狀態(tài)機(jī)的流程會(huì)更加復(fù)雜,而我們最常用到的就是choice彼硫。它類似于java的if語(yǔ)句,作為條件判斷的分支而存在凌箕,讓我們先看一張圖:

image

這張圖表現(xiàn)的是一個(gè)表單(form)的整個(gè)狀態(tài)流程:

  • 創(chuàng)建初始的空白表單( BLANK_FORM)
  • 填寫(WRITE)表單拧篮,成為填充完表單(FULL_FORM)
  • 檢查(CHEKC)表單
  • 如果是表單名(formName)不為null,表單成為待提交表單(CONFIRM_FROM)
  • 提交(SUBMIT)表單牵舱,成為成功提交表單(SUCCESS_FORM)
  • 檢查(CHECK)表單
  • 如果表單名為null串绩,表單成為待處理表單(DEAL_FORM),修改formName
  • 處理(DEAL)表單
  • 如果表單名還是null或者里面有個(gè)“壞”字,表單狀態(tài)變成廢單(FAILED_FORM)
  • 如果表單名稱沒(méi)問(wèn)題芜壁,表單狀態(tài)變成填充完表單狀態(tài)(FULL_FORM),重新走流程
    ??大家不要在意這個(gè)例子的幼稚礁凡,畢竟它還是能用簡(jiǎn)單的方式體現(xiàn)出流程的復(fù)雜性(這話多么的辯證統(tǒng)一)高氮。它有判斷分支(還有兩個(gè)),還有流程的循環(huán)顷牌,還有分支判斷后的直接失敗和分支判斷后的后續(xù)環(huán)節(jié)剪芍,后面我們會(huì)在代碼中告訴大家這里面需要注意的東西。

2窟蓝、代碼實(shí)現(xiàn)

??先上狀態(tài)機(jī)的四件套:States罪裹,Events,Builder和EventConfig(spring statemachine還是蠻簡(jiǎn)單的运挫,來(lái)來(lái)回回就這幾樣?xùn)|西)

public enum ComplexFormStates {
    BLANK_FORM, // 空白表單
    FULL_FORM, // 填寫完表單
    CHECK_CHOICE,//表單校驗(yàn)判斷
    DEAL_CHOICE,//表單處理校驗(yàn)
    DEAL_FORM,//待處理表單
    CONFIRM_FORM, // 校驗(yàn)完表單
    SUCCESS_FORM,// 成功表單
    FAILED_FORM//失敗表單
}

注意一點(diǎn)状共,choice判斷分支本身也是一種狀態(tài),要聲明出來(lái)谁帕,這里是CHECK_CHOICE和DEAL_CHOICE

public enum ComplexFormEvents {
    WRITE, // 填寫
    CHECK,//校驗(yàn)
    DEAL,//處理
    SUBMIT // 提交
}

同樣的分支事件也要聲明峡继,這里是CHECK和DEAL。
大頭是MachineBuilder雇卷,這個(gè)代碼就比較多鬓椭,大家最好對(duì)照著上面這張圖來(lái)看,會(huì)比較清晰

/**
 * 復(fù)雜訂單狀態(tài)機(jī)構(gòu)建器
 */
@Component
public class ComplexFormStateMachineBuilder {

    private final static String MACHINEID = "complexFormMachine";

     /**
      * 構(gòu)建狀態(tài)機(jī)
      * 
     * @param beanFactory
     * @return
     * @throws Exception
     */
    public StateMachine<ComplexFormStates, ComplexFormEvents> build(BeanFactory beanFactory) throws Exception {
         StateMachineBuilder.Builder<ComplexFormStates, ComplexFormEvents> builder = StateMachineBuilder.builder();

         System.out.println("構(gòu)建復(fù)雜表單狀態(tài)機(jī)");

         builder.configureConfiguration()
                .withConfiguration()
                .machineId(MACHINEID)
                .beanFactory(beanFactory);

         builder.configureStates()
                    .withStates()
                    .initial(ComplexFormStates.BLANK_FORM)
                    .choice(ComplexFormStates.CHECK_CHOICE)
                    .choice(ComplexFormStates.DEAL_CHOICE)
                    .states(EnumSet.allOf(ComplexFormStates.class));

         builder.configureTransitions()
                    .withExternal()
                        .source(ComplexFormStates.BLANK_FORM).target(ComplexFormStates.FULL_FORM)
                        .event(ComplexFormEvents.WRITE)
                        .and()
                    .withExternal()
                        .source(ComplexFormStates.FULL_FORM).target(ComplexFormStates.CHECK_CHOICE)
                        .event(ComplexFormEvents.CHECK)
                        .and()
                    .withChoice()
                        .source(ComplexFormStates.CHECK_CHOICE)
                        .first(ComplexFormStates.CONFIRM_FORM, new ComplexFormCheckChoiceGuard())
                        .last(ComplexFormStates.DEAL_FORM)
                        .and()
                    .withExternal()
                        .source(ComplexFormStates.CONFIRM_FORM).target(ComplexFormStates.SUCCESS_FORM)
                        .event(ComplexFormEvents.SUBMIT)
                        .and()
                    .withExternal()
                        .source(ComplexFormStates.DEAL_FORM).target(ComplexFormStates.DEAL_CHOICE)
                        .event(ComplexFormEvents.DEAL)
                        .and()
                    .withChoice()
                        .source(ComplexFormStates.DEAL_CHOICE)
                        .first(ComplexFormStates.FULL_FORM, new ComplexFormDealChoiceGuard())
                        .last(ComplexFormStates.FAILED_FORM);
         return builder.build();
     }
}

這里面出現(xiàn)了幾個(gè)新東西关划,要說(shuō)一下:

  • 在configureStates時(shí)小染,要把每個(gè)分支都要寫上去,我之前寫了ComplexFormStates.CHECK_CHOICE贮折,忘了寫DEAL_CHOICE裤翩,后面的choice就不執(zhí)行,搞得我找了很久调榄,大家要注意(是的踊赠,我犯的就是這種簡(jiǎn)單弱智的錯(cuò)誤,我還找了很久)
  • 在我們熟悉的withExternal之后每庆,我們迎來(lái)了為choice專門準(zhǔn)備的withChoice()和跟隨它的first()筐带,last()。這兩個(gè)代表的就是分支判斷時(shí)TRUE和FALSE的狀態(tài)流程去處缤灵,這里面涉及到的一個(gè)問(wèn)題就是伦籍,TRUE和FALSE的判斷條件是什么呢,根據(jù)啥來(lái)判斷呢腮出?
  • Guard就承擔(dān)了這個(gè)判斷的功能帖鸦,看名字似乎不像。它在spring statemachine本來(lái)是用來(lái)保護(hù)這個(gè)狀態(tài)跳轉(zhuǎn)過(guò)程的胚嘲,所以用guard作儿,但在choice里面,它就是作為判斷代碼而存在的馋劈,代碼如下:
public class ComplexFormCheckChoiceGuard implements Guard<ComplexFormStates, ComplexFormEvents> {

    @Override
    public boolean evaluate(StateContext<ComplexFormStates, ComplexFormEvents> context) {
        boolean returnValue = false;
        Form form = context.getMessage().getHeaders().get("form", Form.class);
        if (form.formName == null) {
            returnValue = false;
        } else {
            returnValue = true;
        }
        return returnValue;
    }

}

它只implements一個(gè)方法evaluate()攻锰,返回boolean類型晾嘶,所以很適合做這個(gè)判斷的功能。另外一個(gè)DEAL_CHOICE的gurad代碼是這樣的

public class ComplexFormDealChoiceGuard implements Guard<ComplexFormStates, ComplexFormEvents> {

    @Override
    public boolean evaluate(StateContext<ComplexFormStates, ComplexFormEvents> context) {
        System.out.println("ComplexFormDealChoiceGuard!!!!!!!!!!!!!");
        boolean returnValue = false;
        Form form = context.getMessage().getHeaders().get("form", Form.class);

        if ((form.formName == null)||(form.formName.indexOf("壞") > -1)) {
            returnValue = false;
        } else {
            returnValue = true;
        }

        System.out.println(form.toString()+" is "+returnValue);
        return returnValue;
    }

}

還有四件套的最后一個(gè)EventConfig:

@WithStateMachine(id="complexFormMachine")
public class ComplexFormEventConfig {
private Logger logger = LoggerFactory.getLogger(getClass());

    /**
     * 當(dāng)前狀態(tài)BLANK_FORM
     */
    @OnTransition(target = "BLANK_FORM")
    public void create() {
        logger.info("---空白復(fù)雜表單---");
    }

    @OnTransition(source = "BLANK_FORM", target = "FULL_FORM")
    public void write(Message<ComplexFormEvents> message) {
        System.out.println("傳遞的參數(shù):" + message.getHeaders().get("form"));
        logger.info("---填寫完復(fù)雜表單---");
    }

    @OnTransition(source = "FULL_FORM", target = "CHECK_CHOICE")
    public void check(Message<ComplexFormEvents> message) {
        System.out.println("傳遞的參數(shù):" + message.getHeaders().get("form").toString());
        logger.info("---校驗(yàn)復(fù)雜表單---");
    }

  //不會(huì)執(zhí)行
    @OnTransition(source = "CHECK_CHOICE", target = "CONFIRM_FORM")
    public void check2confirm(Message<ComplexFormEvents> message) {
        System.out.println("傳遞的參數(shù):" + message.getHeaders().get("form").toString());
        logger.info("---校驗(yàn)表單到待提交表單(choice true)---");
    }

  //不會(huì)執(zhí)行
    @OnTransition(source = "CHECK_CHOICE", target = "DEAL_FORM")
    public void check2deal(Message<ComplexFormEvents> message) {
        System.out.println("傳遞的參數(shù):" + message.getHeaders().get("form").toString());
        logger.info("---校驗(yàn)表單到待提交表單(choice false)---");
    }

    @OnTransition(source = "DEAL_FORM", target = "DEAL_CHOICE")
    public void deal(Message<ComplexFormEvents> message) {
        System.out.println("傳遞的參數(shù):" + message.getHeaders().get("form").toString());
        logger.info("---處理復(fù)雜表單---");
    }

    //不會(huì)執(zhí)行
    @OnTransition(source = "DEAL_CHOICE", target = "FAILED_FORM")
    public void deal2fail(Message<ComplexFormEvents> message) {
        System.out.println("傳遞的參數(shù):" + message.getHeaders().get("form").toString());
        logger.info("---處理復(fù)雜表單失敗(choice false)---");
    }

    //不會(huì)執(zhí)行
    @OnTransition(source = "DEAL_CHOICE", target = "FULL_FORM")
    public void deal2full(Message<ComplexFormEvents> message) {
        System.out.println("傳遞的參數(shù):" + message.getHeaders().get("form").toString());
        logger.info("---處理復(fù)雜表單到重新填寫表單(choice true)---");
    }

    /**
     * CONFIRM_FORM->SUCCESS_FORM 執(zhí)行的動(dòng)作
     */
    @OnTransition(source = "CONFIRM_FORM", target = "SUCCESS_FORM")
    public void submit(Message<ComplexFormEvents> message) {
        System.out.println("傳遞的參數(shù):" + message.getHeaders().get("form").toString());
        logger.info("---表單提交成功---");
    }

}

這邊的代碼沒(méi)有任何特別的地方口注,唯一需要需要注意的是我標(biāo)注的不會(huì)執(zhí)行的這幾個(gè)方法变擒。因?yàn)樵赾hoice判斷的時(shí)候,從一個(gè)狀態(tài)轉(zhuǎn)變到另外一個(gè)狀態(tài)時(shí)寝志,是不會(huì)在eventConfig觸發(fā)方法的娇斑,比如這個(gè)方法:

//不會(huì)執(zhí)行
    @OnTransition(source = "CHECK_CHOICE", target = "CONFIRM_FORM")
    public void check2confirm(Message<ComplexFormEvents> message) {
        System.out.println("傳遞的參數(shù):" + message.getHeaders().get("form").toString());
        logger.info("---校驗(yàn)表單到待提交表單(choice true)---");
    }

我定義了如果用戶從CHECK_CHOICE狀態(tài)如果判斷后變成CONFIRM_FORM,執(zhí)行check2confirm方法材部,但可惜毫缆,狀態(tài)的確變化了,但這個(gè)方法不會(huì)執(zhí)行乐导,只有在做判斷的時(shí)候會(huì)執(zhí)行ComplexFormCheckChoiceGuard的evaluate()苦丁。這就有個(gè)問(wèn)題,在實(shí)際運(yùn)行中物臂,我們的確會(huì)需要在choice做出判斷狀態(tài)改變的時(shí)候要做些業(yè)務(wù)處理旺拉,比如表單check成功后需要通知后續(xù)人員來(lái)處理什么的,這該怎么辦呢棵磷?

  • 簡(jiǎn)單除暴第一招蛾狗,直接在gurad里面處理。這種方法其實(shí)沒(méi)有任何問(wèn)題仪媒,因?yàn)榧热慌袛嗟臉I(yè)務(wù)代碼在這里面沉桌,我們把判斷完成后需要做的事也在這里寫完不就行了。但是算吩,本著無(wú)關(guān)的業(yè)務(wù)能解耦就解耦的原則留凭,我們還有一個(gè)辦法

  • 漂亮解耦第二招,寫個(gè)action偎巢。下面介紹下這個(gè)action蔼夜。

    action,看這個(gè)名字就知道是要搞事情的压昼,之前我們把業(yè)務(wù)代碼都是寫到eventConfig的方法里面挎扰,但其實(shí)可以不怎么干,我們完全可以在每個(gè)狀態(tài)變化的時(shí)候獨(dú)立寫一個(gè)action巢音,這樣的話就能做到業(yè)務(wù)的互不打擾。不如下面這段:

.withChoice()
                        .source(ComplexFormStates.CHECK_CHOICE)
                        .first(ComplexFormStates.CONFIRM_FORM, new ComplexFormCheckChoiceGuard(),new ComplexFormChoiceAction())
                        .last(ComplexFormStates.DEAL_FORM,new ComplexFormChoiceAction())
                        .and()

這是builder里面的代碼片段尽超,我們直接把a(bǔ)ction插入進(jìn)來(lái)官撼,在狀態(tài)變化的時(shí)候就能在action里面處理了,下面是這個(gè)action

的代碼:

public class ComplexFormChoiceAction implements Action<ComplexFormStates, ComplexFormEvents> {

    @Override
    public void execute(StateContext<ComplexFormStates, ComplexFormEvents> context) {
        System.out.println("into ComplexFormChoiceAction");
        Form form = context.getMessage().getHeaders().get("form", Form.class);
        System.out.println(form);
        System.out.println(context.getStateMachine().getState());
    }

}

這里面只有一個(gè)execute的方法似谁,簡(jiǎn)單明了傲绣,我們需要的參數(shù)通過(guò)context傳遞掠哥,其實(shí)還是message,這樣的話秃诵,不同業(yè)務(wù)用不同的action就行了续搀,我們?cè)倩仡^看builder里面插入action的地方:

.first(ComplexFormStates.CONFIRM_FORM, new ComplexFormCheckChoiceGuard(),new ComplexFormChoiceAction(),new ComplexFormChoiceAction())

action可以多個(gè)插入,也就是有多少單獨(dú)的業(yè)務(wù)需要在這里面處理都行菠净,其實(shí)回過(guò)頭來(lái)禁舷,不止在withChoice()里面可以,之前的withExternal()也是可以的毅往,看代碼:

.withExternal()
                        .source(ComplexFormStates.FULL_FORM).target(ComplexFormStates.CHECK_CHOICE)
                        .event(ComplexFormEvents.CHECK)
                        .action(new ComplexFormChoiceAction(),new ComplexFormChoiceAction())
                        .guard(new ComplexFormCheckChoiceGuard())
                        .and()

action可以插入多個(gè)牵咙,但guard在這里恢復(fù)了本來(lái)的作用,保護(hù)狀態(tài)變化攀唯,所以只能插入一個(gè)洁桌。

3、在controller里面看結(jié)果

最后侯嘀,我們還是需要看下運(yùn)行的結(jié)果另凌,我準(zhǔn)備了三個(gè)流程:
  • check成功,成為SUCCESS_FORM
  • check失敗戒幔,deal成功吠谢,回到FULL_FORM
  • check失敗,deal失敗溪食,成為FAILED_FORM

對(duì)應(yīng)的是form1囊卜,form2和form3,看代碼:

@Autowired
    private ComplexFormStateMachineBuilder complexFormStateMachineBuilder;
......
@RequestMapping("/testComplexFormState")
    public void testComplexFormState() throws Exception {

        StateMachine<ComplexFormStates, ComplexFormEvents> stateMachine = complexFormStateMachineBuilder.build(beanFactory);
        System.out.println(stateMachine.getId());

        Form form1 = new Form();
        form1.setId("111");
        form1.setFormName(null);

        Form form2 = new Form();
        form2.setId("222");
        form2.setFormName("好的表單");

        Form form3 = new Form();
        form3.setId("333");
        form3.setFormName(null);

        // 創(chuàng)建流程
        System.out.println("-------------------form1------------------");

        stateMachine.start();
        Message message = MessageBuilder.withPayload(ComplexFormEvents.WRITE).setHeader("form", form1).build();
        stateMachine.sendEvent(message);
        System.out.println("當(dāng)前狀態(tài):" + stateMachine.getState().getId());
        message = MessageBuilder.withPayload(ComplexFormEvents.CHECK).setHeader("form", form1).build();
        stateMachine.sendEvent(message);
        System.out.println("當(dāng)前狀態(tài):" + stateMachine.getState().getId());
        message = MessageBuilder.withPayload(ComplexFormEvents.DEAL).setHeader("form", form1).build();
        stateMachine.sendEvent(message);
        System.out.println("當(dāng)前狀態(tài):" + stateMachine.getState().getId());
        message = MessageBuilder.withPayload(ComplexFormEvents.SUBMIT).setHeader("form", form1).build();
        stateMachine.sendEvent(message);
        System.out.println("最終狀態(tài):" + stateMachine.getState().getId());

        System.out.println("-------------------form2------------------");
        stateMachine = complexFormStateMachineBuilder.build(beanFactory);
        stateMachine.start();
        message = MessageBuilder.withPayload(ComplexFormEvents.WRITE).setHeader("form", form2).build();
        stateMachine.sendEvent(message);
        System.out.println("當(dāng)前狀態(tài):" + stateMachine.getState().getId());
        message = MessageBuilder.withPayload(ComplexFormEvents.CHECK).setHeader("form", form2).build();
        stateMachine.sendEvent(message);
        System.out.println("當(dāng)前狀態(tài):" + stateMachine.getState().getId());
        message = MessageBuilder.withPayload(ComplexFormEvents.DEAL).setHeader("form", form2).build();
        stateMachine.sendEvent(message);
        System.out.println("當(dāng)前狀態(tài):" + stateMachine.getState().getId());
        message = MessageBuilder.withPayload(ComplexFormEvents.SUBMIT).setHeader("form", form2).build();
        stateMachine.sendEvent(message);
        System.out.println("最終狀態(tài):" + stateMachine.getState().getId());

        System.out.println("-------------------form3------------------");
        stateMachine = complexFormStateMachineBuilder.build(beanFactory);
        stateMachine.start();
        message = MessageBuilder.withPayload(ComplexFormEvents.WRITE).setHeader("form", form3).build();
        stateMachine.sendEvent(message);
        System.out.println("當(dāng)前狀態(tài):" + stateMachine.getState().getId());
        message = MessageBuilder.withPayload(ComplexFormEvents.CHECK).setHeader("form", form3).build();
        stateMachine.sendEvent(message);
        System.out.println("當(dāng)前狀態(tài):" + stateMachine.getState().getId());
        form3.setFormName("好的表單");
        message = MessageBuilder.withPayload(ComplexFormEvents.DEAL).setHeader("form", form3).build();
        stateMachine.sendEvent(message);
        System.out.println("當(dāng)前狀態(tài):" + stateMachine.getState().getId());
        message = MessageBuilder.withPayload(ComplexFormEvents.SUBMIT).setHeader("form", form3).build();
        stateMachine.sendEvent(message);
        message = MessageBuilder.withPayload(ComplexFormEvents.CHECK).setHeader("form", form3).build();
        stateMachine.sendEvent(message);
        System.out.println("當(dāng)前狀態(tài):" + stateMachine.getState().getId());
        message = MessageBuilder.withPayload(ComplexFormEvents.SUBMIT).setHeader("form", form3).build();
        stateMachine.sendEvent(message);
        System.out.println("最終狀態(tài):" + stateMachine.getState().getId());
    }
......

看console的結(jié)果就知道正確與否

構(gòu)建復(fù)雜表單狀態(tài)機(jī)
complexFormMachine
-------------------form1------------------
2019-05-13 18:07:19.364  INFO 6188 --- [nio-9991-exec-1] tConfig$$EnhancerBySpringCGLIB$$37df7571 : ---空白復(fù)雜表單---
2019-05-13 18:07:19.368  INFO 6188 --- [nio-9991-exec-1] o.s.s.support.LifecycleObjectSupport     : started org.springframework.statemachine.support.DefaultStateMachineExecutor@16603576
2019-05-13 18:07:19.369  INFO 6188 --- [nio-9991-exec-1] o.s.s.support.LifecycleObjectSupport     : started CONFIRM_FORM BLANK_FORM FAILED_FORM FULL_FORM SUCCESS_FORM DEAL_FORM DEAL_CHOICE CHECK_CHOICE  / BLANK_FORM / uuid=2aa87c74-dd28-4790-9722-d04657eaf046 / id=complexFormMachine
傳遞的參數(shù):Form [id=111, formName=null]
2019-05-13 18:07:19.381  INFO 6188 --- [nio-9991-exec-1] tConfig$$EnhancerBySpringCGLIB$$37df7571 : ---填寫完復(fù)雜表單---
當(dāng)前狀態(tài):FULL_FORM
傳遞的參數(shù):Form [id=111, formName=null]
2019-05-13 18:07:19.386  INFO 6188 --- [nio-9991-exec-1] tConfig$$EnhancerBySpringCGLIB$$37df7571 : ---校驗(yàn)復(fù)雜表單---
ComplexFormCheckChoiceGuard!!!!!!!!!!!!!
Form [id=111, formName=null] is false
into ComplexFormChoiceAction
Form [id=111, formName=null]
ObjectState [getIds()=[FULL_FORM], getClass()=class org.springframework.statemachine.state.ObjectState, hashCode()=381700599, toString()=AbstractState [id=FULL_FORM, pseudoState=null, deferred=[], entryActions=[], exitActions=[], stateActions=[], regions=[], submachine=null]]
當(dāng)前狀態(tài):DEAL_FORM
傳遞的參數(shù):Form [id=111, formName=null]
2019-05-13 18:07:19.389  INFO 6188 --- [nio-9991-exec-1] tConfig$$EnhancerBySpringCGLIB$$37df7571 : ---處理復(fù)雜表單---
ComplexFormDealChoiceGuard!!!!!!!!!!!!!
Form [id=111, formName=null] is false
into ComplexFormChoiceAction
Form [id=111, formName=null]
ObjectState [getIds()=[DEAL_FORM], getClass()=class org.springframework.statemachine.state.ObjectState, hashCode()=980487842, toString()=AbstractState [id=DEAL_FORM, pseudoState=null, deferred=[], entryActions=[], exitActions=[], stateActions=[], regions=[], submachine=null]]
當(dāng)前狀態(tài):FAILED_FORM
最終狀態(tài):FAILED_FORM
-------------------form2------------------
構(gòu)建復(fù)雜表單狀態(tài)機(jī)
2019-05-13 18:07:19.394  INFO 6188 --- [nio-9991-exec-1] tConfig$$EnhancerBySpringCGLIB$$37df7571 : ---空白復(fù)雜表單---
2019-05-13 18:07:19.394  INFO 6188 --- [nio-9991-exec-1] o.s.s.support.LifecycleObjectSupport     : started org.springframework.statemachine.support.DefaultStateMachineExecutor@51adbaad
2019-05-13 18:07:19.394  INFO 6188 --- [nio-9991-exec-1] o.s.s.support.LifecycleObjectSupport     : started CONFIRM_FORM BLANK_FORM FAILED_FORM FULL_FORM SUCCESS_FORM DEAL_FORM DEAL_CHOICE CHECK_CHOICE  / BLANK_FORM / uuid=fa133ea8-bf48-437e-ae35-dc7aa616a23c / id=complexFormMachine
傳遞的參數(shù):Form [id=222, formName=好的表單]
2019-05-13 18:07:19.395  INFO 6188 --- [nio-9991-exec-1] tConfig$$EnhancerBySpringCGLIB$$37df7571 : ---填寫完復(fù)雜表單---
當(dāng)前狀態(tài):FULL_FORM
傳遞的參數(shù):Form [id=222, formName=好的表單]
2019-05-13 18:07:19.396  INFO 6188 --- [nio-9991-exec-1] tConfig$$EnhancerBySpringCGLIB$$37df7571 : ---校驗(yàn)復(fù)雜表單---
ComplexFormCheckChoiceGuard!!!!!!!!!!!!!
Form [id=222, formName=好的表單] is true
into ComplexFormChoiceAction
Form [id=222, formName=好的表單]
ObjectState [getIds()=[FULL_FORM], getClass()=class org.springframework.statemachine.state.ObjectState, hashCode()=249611509, toString()=AbstractState [id=FULL_FORM, pseudoState=null, deferred=[], entryActions=[], exitActions=[], stateActions=[], regions=[], submachine=null]]
當(dāng)前狀態(tài):CONFIRM_FORM
當(dāng)前狀態(tài):CONFIRM_FORM
傳遞的參數(shù):Form [id=222, formName=好的表單]
2019-05-13 18:07:19.399  INFO 6188 --- [nio-9991-exec-1] tConfig$$EnhancerBySpringCGLIB$$37df7571 : ---表單提交成功---
最終狀態(tài):SUCCESS_FORM
-------------------form3------------------
構(gòu)建復(fù)雜表單狀態(tài)機(jī)
2019-05-13 18:07:19.404  INFO 6188 --- [nio-9991-exec-1] tConfig$$EnhancerBySpringCGLIB$$37df7571 : ---空白復(fù)雜表單---
2019-05-13 18:07:19.405  INFO 6188 --- [nio-9991-exec-1] o.s.s.support.LifecycleObjectSupport     : started org.springframework.statemachine.support.DefaultStateMachineExecutor@6f12d1a
2019-05-13 18:07:19.406  INFO 6188 --- [nio-9991-exec-1] o.s.s.support.LifecycleObjectSupport     : started CONFIRM_FORM BLANK_FORM FAILED_FORM FULL_FORM SUCCESS_FORM DEAL_FORM DEAL_CHOICE CHECK_CHOICE  / BLANK_FORM / uuid=03e8c891-eedc-4922-811c-ab375a1e70ae / id=complexFormMachine
傳遞的參數(shù):Form [id=333, formName=null]
2019-05-13 18:07:19.409  INFO 6188 --- [nio-9991-exec-1] tConfig$$EnhancerBySpringCGLIB$$37df7571 : ---填寫完復(fù)雜表單---
當(dāng)前狀態(tài):FULL_FORM
傳遞的參數(shù):Form [id=333, formName=null]
2019-05-13 18:07:19.410  INFO 6188 --- [nio-9991-exec-1] tConfig$$EnhancerBySpringCGLIB$$37df7571 : ---校驗(yàn)復(fù)雜表單---
ComplexFormCheckChoiceGuard!!!!!!!!!!!!!
Form [id=333, formName=null] is false
into ComplexFormChoiceAction
Form [id=333, formName=null]
ObjectState [getIds()=[FULL_FORM], getClass()=class org.springframework.statemachine.state.ObjectState, hashCode()=608638875, toString()=AbstractState [id=FULL_FORM, pseudoState=null, deferred=[], entryActions=[], exitActions=[], stateActions=[], regions=[], submachine=null]]
當(dāng)前狀態(tài):DEAL_FORM
傳遞的參數(shù):Form [id=333, formName=好的表單]
2019-05-13 18:07:19.412  INFO 6188 --- [nio-9991-exec-1] tConfig$$EnhancerBySpringCGLIB$$37df7571 : ---處理復(fù)雜表單---
ComplexFormDealChoiceGuard!!!!!!!!!!!!!
Form [id=333, formName=好的表單] is true
into ComplexFormChoiceAction
Form [id=333, formName=好的表單]
ObjectState [getIds()=[DEAL_FORM], getClass()=class org.springframework.statemachine.state.ObjectState, hashCode()=1203626264, toString()=AbstractState [id=DEAL_FORM, pseudoState=null, deferred=[], entryActions=[], exitActions=[], stateActions=[], regions=[], submachine=null]]
當(dāng)前狀態(tài):FULL_FORM
傳遞的參數(shù):Form [id=333, formName=好的表單]
2019-05-13 18:07:19.413  INFO 6188 --- [nio-9991-exec-1] tConfig$$EnhancerBySpringCGLIB$$37df7571 : ---校驗(yàn)復(fù)雜表單---
ComplexFormCheckChoiceGuard!!!!!!!!!!!!!
Form [id=333, formName=好的表單] is true
into ComplexFormChoiceAction
Form [id=333, formName=好的表單]
ObjectState [getIds()=[FULL_FORM], getClass()=class org.springframework.statemachine.state.ObjectState, hashCode()=608638875, toString()=AbstractState [id=FULL_FORM, pseudoState=null, deferred=[], entryActions=[], exitActions=[], stateActions=[], regions=[], submachine=null]]
當(dāng)前狀態(tài):CONFIRM_FORM
傳遞的參數(shù):Form [id=333, formName=好的表單]
2019-05-13 18:07:19.415  INFO 6188 --- [nio-9991-exec-1] tConfig$$EnhancerBySpringCGLIB$$37df7571 : ---表單提交成功---
最終狀態(tài):SUCCESS_FORM

大家可以跑一下错沃,對(duì)照狀態(tài)機(jī)的流程圖栅组,看下結(jié)果。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末枢析,一起剝皮案震驚了整個(gè)濱河市玉掸,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌醒叁,老刑警劉巖司浪,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異把沼,居然都是意外死亡啊易,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門饮睬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)租谈,“玉大人,你說(shuō)我怎么就攤上這事捆愁「钊ィ” “怎么了窟却?”我有些...
    開(kāi)封第一講書人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)呻逆。 經(jīng)常有香客問(wèn)我夸赫,道長(zhǎng),這世上最難降的妖魔是什么咖城? 我笑而不...
    開(kāi)封第一講書人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任茬腿,我火速辦了婚禮,結(jié)果婚禮上酒繁,老公的妹妹穿的比我還像新娘滓彰。我一直安慰自己,他們只是感情好州袒,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布揭绑。 她就那樣靜靜地躺著,像睡著了一般郎哭。 火紅的嫁衣襯著肌膚如雪他匪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,125評(píng)論 1 297
  • 那天夸研,我揣著相機(jī)與錄音邦蜜,去河邊找鬼。 笑死亥至,一個(gè)胖子當(dāng)著我的面吹牛悼沈,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播姐扮,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼絮供,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了茶敏?” 一聲冷哼從身側(cè)響起壤靶,我...
    開(kāi)封第一講書人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎惊搏,沒(méi)想到半個(gè)月后贮乳,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡恬惯,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年向拆,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片酪耳。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出奖蔓,到底是詐尸還是另有隱情讹堤,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布洲守,位于F島的核電站疑务,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏知允。R本人自食惡果不足惜叙谨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一温鸽、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧手负,春花似錦涤垫、人聲如沸竟终。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至匆绣,卻和暖如春迷守,著一層夾襖步出監(jiān)牢的瞬間犬绒,已是汗流浹背兑凿。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工礼华, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人圣絮。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像捧请,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子活箕,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353