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

資訊專(zhuān)欄INFORMATION COLUMN

spring statemachine的企業(yè)可用級(jí)開(kāi)發(fā)指南2-先跑起來(lái)

lvzishen / 1737人閱讀

摘要:先來(lái)一個(gè),它的主要作用就告訴狀態(tài)機(jī)的初始狀態(tài)應(yīng)該啥樣,然后把整個(gè)狀態(tài)流程都用代碼配置出來(lái)。繼承了類(lèi),表明身份,我就是來(lái)配置狀態(tài)機(jī)的初始狀態(tài),并描繪一下?tīng)顟B(tài)流程的全過(guò)程。

上一篇說(shuō)了很多廢話,這一篇就不嘮叨,先跑起來(lái)

1、來(lái)個(gè)spring boot
去start.spring.io新建一個(gè)springboot的項(xiàng)目,雖然我對(duì)spirngboot也有不少的牢騷,但作為demo的開(kāi)始,還是一個(gè)很好用的腳手架,記得選spring statemachine,為了方便,我還選了web 模塊

點(diǎn)擊generate project 下載到本地,用IDE打開(kāi),順便說(shuō)一句,我用的是java IDE界逼格很低的eclipse,因?yàn)槲乙恢庇盟€不要錢(qián)。

2、跑起來(lái)一個(gè)廢物例子

在本地打開(kāi)后我們首先看pom.xml文件,里面和我們相關(guān)的有這幾段

        2.0.1.RELEASE


            org.springframework.statemachine
            spring-statemachine-starter



                org.springframework.statemachine
                spring-statemachine-bom
                ${spring-statemachine.version}
                pom
                import
    現(xiàn)在就可以在springboot里面用statemachine了,然后我們就開(kāi)始想辦法跑起來(lái)。
    先來(lái)一個(gè)StateMachineConfig,它的主要作用就告訴狀態(tài)機(jī)的初始狀態(tài)應(yīng)該啥樣,然后把整個(gè)狀態(tài)流程都用代碼配置出來(lái)。@Configuration是springboot的注解,表示這個(gè)類(lèi)負(fù)責(zé)配置,@EnableStateMachine表示這個(gè)配置類(lèi)是用在spring statemachine上面的。
package com.skyblue.statemachine.config;

import java.util.EnumSet;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.statemachine.config.EnableStateMachine;
import org.springframework.statemachine.config.EnumStateMachineConfigurerAdapter;
import org.springframework.statemachine.config.builders.StateMachineConfigurationConfigurer;
import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;


@Configuration
@EnableStateMachine
public class StateMachineConfig extends EnumStateMachineConfigurerAdapter {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Override
    public void configure(StateMachineStateConfigurer states) throws Exception {
        states.withStates().initial(OrderStates.UNPAID).states(EnumSet.allOf(OrderStates.class));
    }

    @Override
    public void configure(StateMachineTransitionConfigurer transitions) throws Exception {
        transitions.withExternal().source(OrderStates.UNPAID).target(OrderStates.WAITING_FOR_RECEIVE).event(OrderEvents.PAY).and()
                .withExternal().source(OrderStates.WAITING_FOR_RECEIVE).target(OrderStates.DONE).event(OrderEvents.RECEIVE);
    }
}

它配套需要OrderStates和OrderEvents,代碼如下:

package com.skyblue.statemachine.config;

public enum OrderStates {
    UNPAID, // 待支付
    WAITING_FOR_RECEIVE, // 待收貨
    DONE // 結(jié)束
}
package com.skyblue.statemachine.config;
public enum OrderEvents {
    PAY, // 支付
    RECEIVE // 收貨
}

還有個(gè)OrderSingleEventConfig

package com.skyblue.statemachine.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.messaging.Message;
import org.springframework.statemachine.annotation.OnTransition;
import org.springframework.statemachine.annotation.WithStateMachine;

@WithStateMachine(name="orderSingleMachine")
public class OrderSingleEventConfig {
private Logger logger = LoggerFactory.getLogger(getClass());
    
    /**
     * 當(dāng)前狀態(tài)UNPAID
     */
    @OnTransition(target = "UNPAID")
    public void create() {
        logger.info("---訂單創(chuàng)建,待支付---");
    }
    
    /**
     * UNPAID->WAITING_FOR_RECEIVE 執(zhí)行的動(dòng)作
     */
    @OnTransition(source = "UNPAID", target = "WAITING_FOR_RECEIVE")
    public void pay() {
        logger.info("---用戶完成支付,待收貨---");
    }
    
    /**
     * WAITING_FOR_RECEIVE->DONE 執(zhí)行的動(dòng)作
     */
    @OnTransition(source = "WAITING_FOR_RECEIVE", target = "DONE")
    public void receive() {
        logger.info("---用戶已收貨,訂單完成---");
    }

}

因?yàn)槲冶救瞬粫?huì)用單元測(cè)試,我用了一個(gè)controller來(lái)運(yùn)行,大家見(jiàn)諒

@RestController
@RequestMapping("/statemachine")
public class StateMachineController {
    
    @Autowired
    private StateMachine orderSingleMachine;
    
    @RequestMapping("/testSingleOrderState")
    public void testSingleOrderState() throws Exception {

        // 創(chuàng)建流程
        orderSingleMachine.start();

        // 觸發(fā)PAY事件
        orderSingleMachine.sendEvent(OrderEvents.PAY);

        // 觸發(fā)RECEIVE事件
        orderSingleMachine.sendEvent(OrderEvents.RECEIVE);

        // 獲取最終狀態(tài)
        System.out.println("最終狀態(tài):" + orderSingleMachine.getState().getId());
    }
}

訪問(wèn)頁(yè)面http://localhost:port/statemachine/testSingleOrderState,頁(yè)面沒(méi)有變化,我們看console的日志

2019-04-25 19:14:11.782  INFO 17020 --- [nio-9991-exec-3] tConfig$$EnhancerBySpringCGLIB$$ab30f59f : ---訂單創(chuàng)建,待支付---
2019-04-25 19:14:11.787  INFO 17020 --- [nio-9991-exec-3] o.s.s.support.LifecycleObjectSupport     : started org.springframework.statemachine.support.DefaultStateMachineExecutor@2648176e
2019-04-25 19:14:11.787  INFO 17020 --- [nio-9991-exec-3] o.s.s.support.LifecycleObjectSupport     : started UNPAID DONE WAITING_FOR_RECEIVE  / UNPAID / uuid=93e4f752-55bc-40ef-84e4-6c00cf5a4fc5 / id=null
2019-04-25 19:14:11.797  INFO 17020 --- [nio-9991-exec-3] tConfig$$EnhancerBySpringCGLIB$$ab30f59f : ---用戶完成支付,待收貨---
2019-04-25 19:14:11.800  INFO 17020 --- [nio-9991-exec-3] tConfig$$EnhancerBySpringCGLIB$$ab30f59f : ---用戶已收貨,訂單完成---
最終狀態(tài):DONE

3、我們來(lái)講一下這個(gè)例子

1)描述上圖

其實(shí)OrderStates表達(dá)的就是這張圖的狀態(tài)(state),OrderEvents表達(dá)的就是這張圖狀態(tài)間的事件(event),我們的業(yè)務(wù)代碼就是要塞到事件(event)里面去,處理在狀態(tài)轉(zhuǎn)換間要處理的事情,比如P從UNPAID到WAITING_FOR_RECEIVE中間的PAY事件(event),我們就可能需要調(diào)用支付接口,或者判斷用戶的會(huì)員等級(jí)是不是有支付優(yōu)惠啥的。但state和event是指描述這個(gè)流程的三個(gè)點(diǎn)和兩條線,具體的流程指向要怎么描述呢,就輪到StateMachineConfig出場(chǎng)了。StateMachineConfig繼承了EnumStateMachineConfigurerAdapter類(lèi),表明身份,我就是來(lái)配置狀態(tài)機(jī)的初始狀態(tài),并描繪一下?tīng)顟B(tài)流程的全過(guò)程。

2)塞入業(yè)務(wù)代碼

現(xiàn)在我們知道狀態(tài)(state)和事件(event)了,也描繪了這個(gè)狀態(tài)機(jī)的流程和初始狀態(tài)是什么樣了,然后我們要做什么,當(dāng)然是開(kāi)始把業(yè)務(wù)代碼塞到事件(event)里面去,于是OrderSingleEventConfig登場(chǎng)了。OrderSingleEventConfig里面的create,pay和receive方法就是描繪事件觸發(fā)時(shí)需要做什么,但這三個(gè)方法名其實(shí)是可以自己隨便寫(xiě)的(當(dāng)然最好和event名一樣,避免一年后自己看代碼時(shí)罵當(dāng)年自己為什么那么蠢,至于別人閱讀你的代碼嘛......業(yè)務(wù)代碼誰(shuí)要看你的,別人會(huì)重寫(xiě)的),真正和上面描繪的狀態(tài)流程對(duì)應(yīng)的是@OnTransition,source代表現(xiàn)在的狀態(tài),target代表目標(biāo)狀態(tài),很容易懂的。

3)運(yùn)行狀態(tài)機(jī)

我們?cè)谛枰牡胤揭胍粋€(gè)狀態(tài)機(jī)

@Autowired
private StateMachine orderSingleMachine;

然后運(yùn)行就可以啦

// 創(chuàng)建流程

orderSingleMachine.start();
// 觸發(fā)PAY事件
orderSingleMachine.sendEvent(OrderEvents.PAY);
// 觸發(fā)RECEIVE事件
orderSingleMachine.sendEvent(OrderEvents.RECEIVE);
// 獲取最終狀態(tài)
System.out.println("最終狀態(tài):" + orderSingleMachine.getState().getId());

至此,狀態(tài)機(jī)就跑起來(lái)了,謝謝大家,本教程到此結(jié)束,有疑問(wèn)我也沒(méi)辦法。

4、我是還不想結(jié)束的番外篇

現(xiàn)實(shí)的世界那有這么簡(jiǎn)單,這樣的一個(gè)例子在企業(yè)級(jí)的開(kāi)發(fā)中毫無(wú)用處,大家可以想想這個(gè)例子有啥用,其實(shí)什么問(wèn)題都沒(méi)有解決。大家能想到有哪些問(wèn)題呢,我用我淺薄的開(kāi)發(fā)經(jīng)驗(yàn)一眼就看到了以下幾個(gè)問(wèn)題:

1)整個(gè)項(xiàng)目只有一種狀態(tài)機(jī)流程,我要是想在一個(gè)項(xiàng)目里面又有訂單流程,又有公文審批流程怎么辦,難道和老板講我的狀態(tài)機(jī)demo告訴我,狀態(tài)機(jī)的流程只能選一個(gè)?

2)整個(gè)項(xiàng)目只有一個(gè)狀態(tài)機(jī)流程,你沒(méi)有看眼花,這是另外一個(gè)問(wèn)題。哪怕是只有一種流程,比如訂單流程,其實(shí)也是有很多訂單的流程在同時(shí)跑,而不是像這個(gè)例子,全部訂單共用一個(gè)流程,一個(gè)訂單到WAITING_FOR_RECEIVE狀態(tài)了,其他訂單就不能是UNPAY狀態(tài)了。

3)參數(shù)問(wèn)題,我們做項(xiàng)目,不是為了看日志打出“---訂單創(chuàng)建,待支付---”給我們玩的,而是要處理具體業(yè)務(wù)的,拿訂單流程來(lái)說(shuō)吧,訂單號(hào)怎么傳,狀態(tài)改變時(shí)間怎么回?cái)?shù)據(jù)庫(kù),等等問(wèn)題其實(shí)都需要解決。

4)存儲(chǔ)問(wèn)題,狀態(tài)機(jī)如果有多個(gè),需要的時(shí)候從哪去,暫時(shí)不需要了放哪去,這都是問(wèn)題,所以存儲(chǔ)狀態(tài)機(jī)也是需要解決的。

下一章教程,我們帶著這四個(gè)靈魂問(wèn)題繼續(xù)我們的學(xué)習(xí)之旅

配套代碼地址

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

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

相關(guān)文章

  • spring statemachine企業(yè)可用級(jí)開(kāi)發(fā)指南1-說(shuō)些廢話

    摘要:讓我們先看下?tīng)顟B(tài)機(jī)的概念。下面是狀態(tài)機(jī)模型中的個(gè)要素,即現(xiàn)態(tài)條件動(dòng)作次態(tài)。因?yàn)橛唵魏蛯徟亩加泻芏嗟牧鞒蹋總€(gè)流程都會(huì)產(chǎn)生狀態(tài)的變化,而且流程是這種業(yè)務(wù)的主軸,其他都是圍繞這個(gè)流程和狀態(tài)變化來(lái)考慮的,所以看起來(lái)蠻適合用狀態(tài)機(jī)來(lái)做。 1、背景在我打算學(xué)習(xí)spring statemachine的時(shí)候,我?guī)缀蹩催^(guò)了所有網(wǎng)上的中文教程,基本上都處于淺嘗輒止的階段,有幾篇講的比較深入的,都只是...

    BakerJ 評(píng)論0 收藏0
  • spring statemachine企業(yè)可用級(jí)開(kāi)發(fā)指南6-持久化

    摘要:目前為止,我們都是從狀態(tài)流程的開(kāi)始階段創(chuàng)建一個(gè)狀態(tài)機(jī),然后一路走下去。然后就可以愉快的在里面看怎么用了發(fā)送事件持久化恢復(fù)狀態(tài)機(jī)后的狀態(tài)為執(zhí)行完保存后,大家可以自己在客戶端查看以下,是不是有內(nèi)容保存進(jìn)去了。 目前為止,我們都是從狀態(tài)流程的開(kāi)始階段創(chuàng)建一個(gè)狀態(tài)機(jī),然后一路走下去。但在實(shí)際業(yè)務(wù)中,狀態(tài)機(jī)可能需要在某個(gè)環(huán)節(jié)停留,等待其他業(yè)務(wù)的觸發(fā),然后再繼續(xù)下面的流程。比如訂單,可能在支付環(huán)節(jié)...

    Jioby 評(píng)論0 收藏0
  • spring statemachine企業(yè)可用級(jí)開(kāi)發(fā)指南7-偽持久化和中間段狀態(tài)機(jī)

    摘要:在實(shí)際的企業(yè)開(kāi)發(fā)中,不可能所有情況都是從頭到尾的按狀態(tài)流程來(lái),會(huì)有很多意外,比如歷史數(shù)據(jù),故障重啟后的遺留流程,所以這種可以任意調(diào)節(jié)狀態(tài)的才是我們需要的狀態(tài)機(jī)。 1、偽持久化和中間段的狀態(tài)機(jī)我們?cè)O(shè)想一個(gè)業(yè)務(wù)場(chǎng)景,就比如訂單吧,我們一般的設(shè)計(jì)都會(huì)把訂單狀態(tài)存到訂單表里面,其他的業(yè)務(wù)信息也都有表保存,而狀態(tài)機(jī)的主要作用其實(shí)是規(guī)范整個(gè)訂單業(yè)務(wù)流程的狀態(tài)和事件,所以狀態(tài)機(jī)要不要保存真的不重要,...

    shiyang6017 評(píng)論0 收藏0
  • spring statemachine企業(yè)可用級(jí)開(kāi)發(fā)指南5-傳遞參數(shù)message

    摘要:創(chuàng)建了后,狀態(tài)機(jī)就可以不只是傳一個(gè),可以組合和數(shù)據(jù)內(nèi)容一起發(fā)送給狀態(tài)機(jī)變化的處理類(lèi)了。到這里為止,狀態(tài)機(jī)通過(guò)對(duì)象就和其他的業(yè)務(wù)代碼做到了數(shù)據(jù)連接。 在企業(yè)開(kāi)發(fā)中,數(shù)據(jù)在不同的業(yè)務(wù)間傳輸是最常見(jiàn)的工作,所以雖然我們的主架構(gòu)是用的狀態(tài)機(jī),也就是從流程狀態(tài)的角度來(lái)看待這個(gè)項(xiàng)目,但在具體業(yè)務(wù)中,每個(gè)狀態(tài)的轉(zhuǎn)變中會(huì)牽涉到各類(lèi)業(yè)務(wù),這些業(yè)務(wù)有些需要收到狀態(tài)機(jī)變化的通知,需要把狀態(tài)值傳遞給業(yè)務(wù)類(lèi)和業(yè)...

    YacaToy 評(píng)論0 收藏0
  • spring statemachine企業(yè)可用級(jí)開(kāi)發(fā)指南4-多種狀態(tài)機(jī)共存

    摘要:目前為止,多個(gè)狀態(tài)機(jī)和多種狀態(tài)機(jī)都可以在里面實(shí)現(xiàn)了,下一章我們來(lái)解決下?tīng)顟B(tài)機(jī)和實(shí)際業(yè)務(wù)間的數(shù)據(jù)傳輸問(wèn)題,畢竟我們不是為了讓狀態(tài)機(jī)自個(gè)獨(dú)自玩耍,和業(yè)務(wù)數(shù)據(jù)互通有無(wú)才是企業(yè)開(kāi)發(fā)的正道。 在上一章的例子中,我們實(shí)現(xiàn)了多個(gè)狀態(tài)機(jī)并存執(zhí)行,不同的訂單有各自的狀態(tài)機(jī)運(yùn)行,但只有一種狀態(tài)機(jī),這顯然不能滿足實(shí)際業(yè)務(wù)的要求,比如我就遇到了訂單流程和公文審批流程在同一個(gè)項(xiàng)目的情況,所以我們這一章講怎么讓多...

    boredream 評(píng)論0 收藏0

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

0條評(píng)論

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