天天看點

spring statemachine的企業可用級開發指南8-複雜狀态機的實作,choice,guard和action1、講講複雜流程的需求    2、代碼實作3、在controller裡面看結果4、繼續廢話

1、講講複雜流程的需求    

除了上面文章裡面提到的一根筋狀态機流程,實際的企業應用中狀态機的流程會更加複雜,而我們最常用到的就是choice。它類似于java的if語句,作為條件判斷的分支而存在,讓我們先看一張圖:

spring statemachine的企業可用級開發指南8-複雜狀态機的實作,choice,guard和action1、講講複雜流程的需求    2、代碼實作3、在controller裡面看結果4、繼續廢話

    這張圖表現的是一個表單(form)的整個狀态流程:

  • 建立初始的空白表單( BLANK_FORM)
  • 填寫(WRITE)表單,成為填充完表單(FULL_FORM)
  • 檢查(CHEKC)表單
    • 如果是表單名(formName)不為null,表單成為待送出表單(CONFIRM_FROM)
    • 送出(SUBMIT)表單,成為成功送出表單(SUCCESS_FORM)
  • 檢查(CHECK)表單
    • 如果表單名為null,表單成為待處理表單(DEAL_FORM),修改formName
    • 處理(DEAL)表單
      • 如果表單名還是null或者裡面有個“壞”字,表單狀态變成廢單(FAILED_FORM)
      • 如果表單名稱沒問題,表單狀态變成填充完表單狀态(FULL_FORM),重新走流程

    大家不要在意這個例子的幼稚,畢竟它還是能用簡單的方式展現出流程的複雜性(這話多麼的辯證統一)。它有判斷分支(還有兩個),還有流程的循環,還有分支判斷後的直接失敗和分支判斷後的後續環節,後面我們會在代碼中告訴大家這裡面需要注意的東西。

2、代碼實作

    先上狀态機的四件套:States,Events,Builder和EventConfig(spring statemachine還是蠻簡單的,來來回回就這幾樣東西)

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

注意一點,choice判斷分支本身也是一種狀态,要聲明出來,這裡是CHECK_CHOICE和DEAL_CHOICE

public enum ComplexFormEvents {
	WRITE, // 填寫
	CHECK,//校驗
	DEAL,//處理
	SUBMIT // 送出
}
           

同樣的分支事件也要聲明,這裡是CHECK和DEAL。

大頭是MachineBuilder,這個代碼就比較多,大家最好對照着上面這張圖來看,會比較清晰

/**
 * 複雜訂單狀态機建構器
 */
@Component
public class ComplexFormStateMachineBuilder {

	private final static String MACHINEID = "complexFormMachine";
	
	 /**
	  * 建構狀态機
	  * 
	 * @param beanFactory
	 * @return
	 * @throws Exception
	 */
	public StateMachine<ComplexFormStates, ComplexFormEvents> build(BeanFactory beanFactory) throws Exception {
		 StateMachineBuilder.Builder<ComplexFormStates, ComplexFormEvents> builder = StateMachineBuilder.builder();
		 
		 System.out.println("建構複雜表單狀态機");
		 
		 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();
	 }
}
           

這裡面出現了幾個新東西,要說一下:

  • 在configureStates時,要把每個分支都要寫上去,我之前寫了ComplexFormStates.CHECK_CHOICE,忘了寫DEAL_CHOICE,後面的choice就不執行,搞得我找了很久,大家要注意(是的,我犯的就是這種簡單弱智的錯誤,我還找了很久)
  • 在我們熟悉的withExternal之後,我們迎來了為choice專門準備的withChoice()和跟随它的first(),last()。這兩個代表的就是分支判斷時TRUE和FALSE的狀态流程去處,這裡面涉及到的一個問題就是,TRUE和FALSE的判斷條件是什麼呢,根據啥來判斷呢?
  • Guard就承擔了這個判斷的功能,看名字似乎不像。它在spring statemachine本來是用來保護這個狀态跳轉過程的,是以用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一個方法evaluate(),傳回boolean類型,是以很适合做這個判斷的功能。另外一個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;
	}

}
           

還有四件套的最後一個EventConfig:

@WithStateMachine(id="complexFormMachine")
public class ComplexFormEventConfig {
private Logger logger = LoggerFactory.getLogger(getClass());
	
    /**
     * 目前狀态BLANK_FORM
     */
    @OnTransition(target = "BLANK_FORM")
    public void create() {
        logger.info("---空白複雜表單---");
    }
    
    @OnTransition(source = "BLANK_FORM", target = "FULL_FORM")
    public void write(Message<ComplexFormEvents> message) {
    	System.out.println("傳遞的參數:" + message.getHeaders().get("form"));
        logger.info("---填寫完複雜表單---");
    }
    
    @OnTransition(source = "FULL_FORM", target = "CHECK_CHOICE")
    public void check(Message<ComplexFormEvents> message) {
    	System.out.println("傳遞的參數:" + message.getHeaders().get("form").toString());
        logger.info("---校驗複雜表單---");
    }
    
  //不會執行
    @OnTransition(source = "CHECK_CHOICE", target = "CONFIRM_FORM")
    public void check2confirm(Message<ComplexFormEvents> message) {
    	System.out.println("傳遞的參數:" + message.getHeaders().get("form").toString());
        logger.info("---校驗表單到待送出表單(choice true)---");
    }
    
  //不會執行
    @OnTransition(source = "CHECK_CHOICE", target = "DEAL_FORM")
    public void check2deal(Message<ComplexFormEvents> message) {
    	System.out.println("傳遞的參數:" + message.getHeaders().get("form").toString());
        logger.info("---校驗表單到待送出表單(choice false)---");
    }
    
    @OnTransition(source = "DEAL_FORM", target = "DEAL_CHOICE")
    public void deal(Message<ComplexFormEvents> message) {
    	System.out.println("傳遞的參數:" + message.getHeaders().get("form").toString());
        logger.info("---處理複雜表單---");
    }
    
    //不會執行
    @OnTransition(source = "DEAL_CHOICE", target = "FAILED_FORM")
    public void deal2fail(Message<ComplexFormEvents> message) {
    	System.out.println("傳遞的參數:" + message.getHeaders().get("form").toString());
        logger.info("---處理複雜表單失敗(choice false)---");
    }
    
    //不會執行
    @OnTransition(source = "DEAL_CHOICE", target = "FULL_FORM")
    public void deal2full(Message<ComplexFormEvents> message) {
    	System.out.println("傳遞的參數:" + message.getHeaders().get("form").toString());
        logger.info("---處理複雜表單到重新填寫表單(choice true)---");
    }
    
   
    
    /**
     * CONFIRM_FORM->SUCCESS_FORM 執行的動作
     */
    @OnTransition(source = "CONFIRM_FORM", target = "SUCCESS_FORM")
    public void submit(Message<ComplexFormEvents> message) {
    	System.out.println("傳遞的參數:" + message.getHeaders().get("form").toString());
        logger.info("---表單送出成功---");
    }

}
           

這邊的代碼沒有任何特别的地方,唯一需要需要注意的是我标注的不會執行的這幾個方法。因為在choice判斷的時候,從一個狀态轉變到另外一個狀态時,是不會在eventConfig觸發方法的,比如這個方法:

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

我定義了如果使用者從CHECK_CHOICE狀态如果判斷後變成CONFIRM_FORM,執行check2confirm方法,但可惜,狀态的确變化了,但這個方法不會執行,隻有在做判斷的時候會執行ComplexFormCheckChoiceGuard的evaluate()。這就有個問題,在實際運作中,我們的确會需要在choice做出判斷狀态改變的時候要做些業務處理,比如表單check成功後需要通知後續人員來處理什麼的,這該怎麼辦呢?

  • 簡單除暴第一招,直接在gurad裡面處理。這種方法其實沒有任何問題,因為既然判斷的業務代碼在這裡面,我們把判斷完成後需要做的事也在這裡寫完不就行了。但是,本着無關的業務能解耦就解耦的原則,我們還有一個辦法
  • 漂亮解耦第二招,寫個action。下面介紹下這個action。

    action,看這個名字就知道是要搞事情的,之前我們把業務代碼都是寫到eventConfig的方法裡面,但其實可以不怎麼幹,我們完全可以在每個狀态變化的時候獨立寫一個action,這樣的話就能做到業務的互不打擾。不如下面這段:

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

這是builder裡面的代碼片段,我們直接把action插入進來,在狀态變化的時候就能在action裡面處理了,下面是這個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());
	}

}
           

這裡面隻有一個execute的方法,簡單明了,我們需要的參數通過context傳遞,其實還是message,這樣的話,不同業務用不同的action就行了,我們再回頭看builder裡面插入action的地方:

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

action可以多個插入,也就是有多少單獨的業務需要在這裡面處理都行,其實回過頭來,不止在withChoice()裡面可以,之前的withExternal()也是可以的,看代碼:

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

action可以插入多個,但guard在這裡恢複了本來的作用,保護狀态變化,是以隻能插入一個。

3、在controller裡面看結果

    最後,我們還是需要看下運作的結果,我準備了三個流程:

  • check成功,成為SUCCESS_FORM
  • check失敗,deal成功,回到FULL_FORM
  • check失敗,deal失敗,成為FAILED_FORM

對應的是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);

		// 建立流程
		System.out.println("-------------------form1------------------");
		
		stateMachine.start();
		Message message = MessageBuilder.withPayload(ComplexFormEvents.WRITE).setHeader("form", form1).build();
		stateMachine.sendEvent(message);
		System.out.println("目前狀态:" + stateMachine.getState().getId());
		message = MessageBuilder.withPayload(ComplexFormEvents.CHECK).setHeader("form", form1).build();
		stateMachine.sendEvent(message);
		System.out.println("目前狀态:" + stateMachine.getState().getId());
		message = MessageBuilder.withPayload(ComplexFormEvents.DEAL).setHeader("form", form1).build();
		stateMachine.sendEvent(message);
		System.out.println("目前狀态:" + stateMachine.getState().getId());
		message = MessageBuilder.withPayload(ComplexFormEvents.SUBMIT).setHeader("form", form1).build();
		stateMachine.sendEvent(message);
		System.out.println("最終狀态:" + 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("目前狀态:" + stateMachine.getState().getId());
		message = MessageBuilder.withPayload(ComplexFormEvents.CHECK).setHeader("form", form2).build();
		stateMachine.sendEvent(message);
		System.out.println("目前狀态:" + stateMachine.getState().getId());
		message = MessageBuilder.withPayload(ComplexFormEvents.DEAL).setHeader("form", form2).build();
		stateMachine.sendEvent(message);
		System.out.println("目前狀态:" + stateMachine.getState().getId());
		message = MessageBuilder.withPayload(ComplexFormEvents.SUBMIT).setHeader("form", form2).build();
		stateMachine.sendEvent(message);
		System.out.println("最終狀态:" + 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("目前狀态:" + stateMachine.getState().getId());
		message = MessageBuilder.withPayload(ComplexFormEvents.CHECK).setHeader("form", form3).build();
		stateMachine.sendEvent(message);
		System.out.println("目前狀态:" + stateMachine.getState().getId());
		form3.setFormName("好的表單");
		message = MessageBuilder.withPayload(ComplexFormEvents.DEAL).setHeader("form", form3).build();
		stateMachine.sendEvent(message);
		System.out.println("目前狀态:" + 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("目前狀态:" + stateMachine.getState().getId());
		message = MessageBuilder.withPayload(ComplexFormEvents.SUBMIT).setHeader("form", form3).build();
		stateMachine.sendEvent(message);
		System.out.println("最終狀态:" + stateMachine.getState().getId());
	}
......
           

看console的結果就知道正确與否

建構複雜表單狀态機
complexFormMachine
-------------------form1------------------
2019-05-13 18:07:19.364  INFO 6188 --- [nio-9991-exec-1] tConfig$$EnhancerBySpringCGLIB$$37df7571 : ---空白複雜表單---
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
傳遞的參數:Form [id=111, formName=null]
2019-05-13 18:07:19.381  INFO 6188 --- [nio-9991-exec-1] tConfig$$EnhancerBySpringCGLIB$$37df7571 : ---填寫完複雜表單---
目前狀态:FULL_FORM
傳遞的參數:Form [id=111, formName=null]
2019-05-13 18:07:19.386  INFO 6188 --- [nio-9991-exec-1] tConfig$$EnhancerBySpringCGLIB$$37df7571 : ---校驗複雜表單---
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]]
目前狀态:DEAL_FORM
傳遞的參數:Form [id=111, formName=null]
2019-05-13 18:07:19.389  INFO 6188 --- [nio-9991-exec-1] tConfig$$EnhancerBySpringCGLIB$$37df7571 : ---處理複雜表單---
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]]
目前狀态:FAILED_FORM
最終狀态:FAILED_FORM
-------------------form2------------------
建構複雜表單狀态機
2019-05-13 18:07:19.394  INFO 6188 --- [nio-9991-exec-1] tConfig$$EnhancerBySpringCGLIB$$37df7571 : ---空白複雜表單---
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
傳遞的參數:Form [id=222, formName=好的表單]
2019-05-13 18:07:19.395  INFO 6188 --- [nio-9991-exec-1] tConfig$$EnhancerBySpringCGLIB$$37df7571 : ---填寫完複雜表單---
目前狀态:FULL_FORM
傳遞的參數:Form [id=222, formName=好的表單]
2019-05-13 18:07:19.396  INFO 6188 --- [nio-9991-exec-1] tConfig$$EnhancerBySpringCGLIB$$37df7571 : ---校驗複雜表單---
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]]
目前狀态:CONFIRM_FORM
目前狀态:CONFIRM_FORM
傳遞的參數:Form [id=222, formName=好的表單]
2019-05-13 18:07:19.399  INFO 6188 --- [nio-9991-exec-1] tConfig$$EnhancerBySpringCGLIB$$37df7571 : ---表單送出成功---
最終狀态:SUCCESS_FORM
-------------------form3------------------
建構複雜表單狀态機
2019-05-13 18:07:19.404  INFO 6188 --- [nio-9991-exec-1] tConfig$$EnhancerBySpringCGLIB$$37df7571 : ---空白複雜表單---
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
傳遞的參數:Form [id=333, formName=null]
2019-05-13 18:07:19.409  INFO 6188 --- [nio-9991-exec-1] tConfig$$EnhancerBySpringCGLIB$$37df7571 : ---填寫完複雜表單---
目前狀态:FULL_FORM
傳遞的參數:Form [id=333, formName=null]
2019-05-13 18:07:19.410  INFO 6188 --- [nio-9991-exec-1] tConfig$$EnhancerBySpringCGLIB$$37df7571 : ---校驗複雜表單---
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]]
目前狀态:DEAL_FORM
傳遞的參數:Form [id=333, formName=好的表單]
2019-05-13 18:07:19.412  INFO 6188 --- [nio-9991-exec-1] tConfig$$EnhancerBySpringCGLIB$$37df7571 : ---處理複雜表單---
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]]
目前狀态:FULL_FORM
傳遞的參數:Form [id=333, formName=好的表單]
2019-05-13 18:07:19.413  INFO 6188 --- [nio-9991-exec-1] tConfig$$EnhancerBySpringCGLIB$$37df7571 : ---校驗複雜表單---
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]]
目前狀态:CONFIRM_FORM
傳遞的參數:Form [id=333, formName=好的表單]
2019-05-13 18:07:19.415  INFO 6188 --- [nio-9991-exec-1] tConfig$$EnhancerBySpringCGLIB$$37df7571 : ---表單送出成功---
最終狀态:SUCCESS_FORM
           

大家可以跑一下,對照狀态機的流程圖,看下結果。

4、繼續廢話

    其實spring statemachine寫到這裡,基本上已經可以上手去做企業開發了。當然,spring statemachine裡面還有很多其他的東西,大部分是處理複雜狀态機流程的,以後有機會我們再展開講。

源代碼位址