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

資訊專欄INFORMATION COLUMN

spring statemachine的企業(yè)可用級(jí)開(kāi)發(fā)指南6-持久化

Jioby / 3027人閱讀

摘要:目前為止,我們都是從狀態(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é)需要等待一個(gè)剁手的用戶隔天再下單,所以這里面涉及到一個(gè)創(chuàng)建的狀態(tài)機(jī)該何去何從的問(wèn)題。在spring statemachine中,給出來(lái)的辦法就是保存起來(lái),到需要的時(shí)候取出來(lái)用。

1、持久化到本地內(nèi)存
嚴(yán)格來(lái)說(shuō),你完全可以自己保存狀態(tài)機(jī),比如我就自己用map保存下來(lái)了。

public class MachineMap {

public static Map> orderMap = new HashMap>();
public static Map> formMap = new HashMap>();

}
這個(gè)代碼一看就明白,我用唯一id作為key(order就是orderId,form就是formId),把狀態(tài)機(jī)保存到map表里面,在實(shí)際的業(yè)務(wù)中,自由存取

@RequestMapping("/sendEvent")

void sendEvent(String machineId,String events,String id) throws Exception{
    if(machineId.equals("form")) {
        StateMachine sm = MachineMap.formMap.get(id);
        Form form = new Form();
        form.setId(id);
        if(sm == null) {
            if(events.equals("WRITE")) {
                sm = formStateMachineBuilder.build(beanFactory);
                sm.start();
                MachineMap.formMap.put(id, sm);
            }else {
                System.out.println("該表單流程尚未開(kāi)始,不能做"+events+"轉(zhuǎn)換");
                return;
            }
        }
        
        Message message = MessageBuilder.withPayload(FormEvents.valueOf(events)).setHeader("form", form).build();
        sm.sendEvent(message);
    }
    if(machineId.equals("order")) {
        StateMachine sm = MachineMap.orderMap.get(id);
        Order order = new Order();
        order.setId(id);
        if(sm == null) {
            if(events.equals("PAY")) {
                sm = orderStateMachineBuilder.build(beanFactory);
                sm.start();
                MachineMap.orderMap.put(id, sm);
            }else {
                System.out.println("該訂單流程尚未開(kāi)始,不能做"+events+"轉(zhuǎn)換");
                return;
            }
            
        }
        Message message = MessageBuilder.withPayload(OrderEvents.valueOf(events)).setHeader("order", order).setHeader("test","test1").build();
        sm.sendEvent(message);
    }
}

在這段代碼里面,我根據(jù)不同種類的狀態(tài)機(jī)去map取和id對(duì)應(yīng)的狀態(tài)機(jī),如果狀態(tài)機(jī)沒(méi)在map里面,就創(chuàng)建一個(gè),然后塞進(jìn)map表。其實(shí)寫(xiě)這個(gè)代碼,并沒(méi)有其他意思,只是為了告訴你,spring打算管理你的map表,所以出了一個(gè)接口來(lái)規(guī)范這件事:

import java.util.HashMap;
import java.util.Map;

import org.springframework.statemachine.StateMachineContext;
import org.springframework.statemachine.StateMachinePersist;
import org.springframework.stereotype.Component;

/**

在內(nèi)存中持久化狀態(tài)機(jī)

*/
@Component
public class InMemoryStateMachinePersist implements StateMachinePersist {

private Map> map = new HashMap>();

@Override
public void write(StateMachineContext context, String contextObj) throws Exception {
    map.put(contextObj, context);
}

@Override
public StateMachineContext read(String contextObj) throws Exception {
    return map.get(contextObj);
}

}
這個(gè)接口非常簡(jiǎn)單,就是write和read,但他保存的對(duì)象是StateMachineContext,不是StateMachine,所以我們還不能直接用它,需要配置一下。

import org.springframework.statemachine.StateMachinePersist;
......
import org.springframework.statemachine.persist.StateMachinePersister;
@Configuration
public class PersistConfig {


@Autowired
private InMemoryStateMachinePersist inMemoryStateMachinePersist;

/**
 * 注入StateMachinePersister對(duì)象
 * 
 * @return
 */
@Bean(name="orderMemoryPersister")
public StateMachinePersister getPersister() {
    return new DefaultStateMachinePersister<>(inMemoryStateMachinePersist);
}

}
這里有個(gè)坑,InMemoryStateMachinePersist 實(shí)現(xiàn)的接口是

org.springframework.statemachine.StateMachinePersist
,但在PersistConfig 里面,getPersister()方法返回的值類型是StateMachinePersister類型,看著很像,但并不是上面的這個(gè)接口,而是org.springframework.statemachine.persist.StateMachinePersister接口,為了表示這個(gè)坑對(duì)我的傷害,我要強(qiáng)調(diào)一下兩個(gè)接口:

package org.springframework.statemachine;
public interface StateMachinePersist {

void write(StateMachineContext context, T contextObj) throws Exception;
StateMachineContext read(T contextObj) throws Exception;

}
package org.springframework.statemachine.persist;
import org.springframework.statemachine.StateMachine;
public interface StateMachinePersister {

void persist(StateMachine stateMachine, T contextObj) throws Exception;
StateMachine restore(StateMachine stateMachine, T contextObj) throws Exception;

}
這兩個(gè)接口名字很類似,很容易搞混,但下面的是有er的,包名也不同的。StateMachinePersister是可以直接保存StateMachine對(duì)象的,所以我們需要先實(shí)現(xiàn)上面的StateMachinePersist,然后再一個(gè)Config類里面轉(zhuǎn)換成下面的StateMachinePersister,轉(zhuǎn)換的代碼就在上面的PersistConfig類里。

然后我們就能在controller里面使用了

@Resource(name="orderMemoryPersister")
private StateMachinePersister orderMemorypersister;

......

//保存狀態(tài)機(jī)
@RequestMapping("/testMemoryPersister")

public void tesMemorytPersister(String id) throws Exception {
    StateMachine stateMachine = orderStateMachineBuilder.build(beanFactory);
    stateMachine.start();
    
    //發(fā)送PAY事件
    stateMachine.sendEvent(OrderEvents.PAY);
    Order order = new Order();
    order.setId(id);
    
    //持久化stateMachine
    orderMemorypersister.persist(stateMachine, order.getId());

}

//取出狀態(tài)機(jī)
@RequestMapping("/testMemoryPersisterRestore")

public void testMemoryRestore(String id) throws Exception {
    StateMachine stateMachine = orderStateMachineBuilder.build(beanFactory);
    orderMemorypersister.restore(stateMachine, id);
    System.out.println("恢復(fù)狀態(tài)機(jī)后的狀態(tài)為:" + stateMachine.getState().getId());
}

2、持久化到redis
真正的業(yè)務(wù)中,一般都是多臺(tái)機(jī)分布式運(yùn)行,所以如果狀態(tài)機(jī)只能保存在本地內(nèi)容,就不能用在分布式應(yīng)用上了。spring提供了一個(gè)方便的辦法,使用redis解決這個(gè)問(wèn)題。讓我們看看怎么弄。

pom文件引入spring-statemachine-redis

    
        org.springframework.statemachine
        spring-statemachine-redis
        1.2.9.RELEASE
    

在springboot配置文件里面加上redis參數(shù),我這是application.properties

REDIS (RedisProperties) Redis數(shù)據(jù)庫(kù)索引(默認(rèn)為0)

spring.redis.database=0

Redis服務(wù)器地址

spring.redis.host=localhost

Redis服務(wù)器連接端口

spring.redis.port=6379

Redis服務(wù)器連接密碼(默認(rèn)為空)

spring.redis.password=

連接池最大連接數(shù)(使用負(fù)值表示沒(méi)有限制)

spring.redis.pool.max-active=8

連接池最大阻塞等待時(shí)間(使用負(fù)值表示沒(méi)有限制)

spring.redis.pool.max-wait=-1

連接池中的最大空閑連接

spring.redis.pool.max-idle=8

連接池中的最小空閑連接

spring.redis.pool.min-idle=0

連接超時(shí)時(shí)間(毫秒)

spring.redis.timeout=0
保證配置的redis開(kāi)啟并能用,我們繼續(xù)。回到我們熟悉的PersistConfig

@Configuration
public class PersistConfig {

@Autowired
private RedisConnectionFactory redisConnectionFactory;


/**
 * 注入RedisStateMachinePersister對(duì)象
 * 
 * @return
 */
@Bean(name = "orderRedisPersister")
public RedisStateMachinePersister redisPersister() {
    return new RedisStateMachinePersister<>(redisPersist());
}

/**
 * 通過(guò)redisConnectionFactory創(chuàng)建StateMachinePersist
 * 
 * @return
 */
public StateMachinePersist redisPersist() {
    RedisStateMachineContextRepository repository = new RedisStateMachineContextRepository<>(redisConnectionFactory);
    return new RepositoryStateMachinePersist<>(repository);
}

}
這個(gè)套路和上面保存到本地內(nèi)存是一樣一樣的,先生成一個(gè)StateMachinePersist,這里是通過(guò)RedisConnectionFactory生成RepositoryStateMachinePersist,然后再包裝輸出StateMachinePersister,這里是RedisStateMachinePersister。然后就可以愉快的在controller里面看怎么用了

@Resource(name="orderRedisPersister")
private StateMachinePersister orderRedisPersister;

......

@RequestMapping("/testRedisPersister")

public void testRedisPersister(String id) throws Exception {
    StateMachine stateMachine = orderStateMachineBuilder.build(beanFactory);
    stateMachine.start();
    Order order = new Order();
    order.setId(id);
    //發(fā)送PAY事件
    Message message = MessageBuilder.withPayload(OrderEvents.PAY).setHeader("order", order).build();
    stateMachine.sendEvent(message);
    //持久化stateMachine
    orderRedisPersister.persist(stateMachine, order.getId());
}

@RequestMapping("/testRedisPersisterRestore")
public void testRestore(String id) throws Exception {
    StateMachine stateMachine = orderStateMachineBuilder.build(beanFactory);
    orderRedisPersister.restore(stateMachine, id);
    System.out.println("恢復(fù)狀態(tài)機(jī)后的狀態(tài)為:" + stateMachine.getState().getId());
}

執(zhí)行完redis保存statemachine后,大家可以自己在redis客戶端查看以下,是不是有內(nèi)容保存進(jìn)去了。

3、下期預(yù)告
無(wú)論是本地內(nèi)存還是分布式緩存,似乎都不是很可靠的持久化,但下一章會(huì)告訴大家,保不保存也就那么點(diǎn)大的事,沒(méi)保存我們就再創(chuàng)建一個(gè)就好了。但另外一個(gè)問(wèn)題就浮出水面了,狀態(tài)機(jī)執(zhí)行到中間的時(shí)候創(chuàng)建狀態(tài)機(jī),怎么在中間繼續(xù)執(zhí)行,之前的可都是從頭開(kāi)始執(zhí)行的,這個(gè)問(wèn)題,下一章解決。

碼云配套代碼地址

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

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

相關(guān)文章

  • 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ī)變化的處理類了。到這里為止,狀態(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ì)牽涉到各類業(yè)務(wù),這些業(yè)務(wù)有些需要收到狀態(tài)機(jī)變化的通知,需要把狀態(tài)值傳遞給業(yè)務(wù)類和業(yè)...

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

    摘要:雖然多個(gè)狀態(tài)機(jī)的問(wèn)題解決了,但是對(duì)于實(shí)際的企業(yè)應(yīng)用而言,還是有問(wèn)題。這個(gè)問(wèn)題就用到了狀態(tài)機(jī)的持久化,我們下一章就談?wù)劤志没瘑?wèn)題。 1、多個(gè)狀態(tài)機(jī)的搞法在實(shí)際的企業(yè)應(yīng)用中,基本不可能只有一個(gè)狀態(tài)機(jī)流程在跑,比如訂單,肯定是很多個(gè)訂單在運(yùn)行,每個(gè)訂單都有自己的訂單狀態(tài)機(jī)流程,但上一章的例子,大家可以試一下,當(dāng)執(zhí)行到一個(gè)狀態(tài)時(shí),再次刷新頁(yè)面,不會(huì)有任何日志出現(xiàn),當(dāng)一個(gè)狀態(tài)流程執(zhí)行到某個(gè)狀態(tài),...

    zhongmeizhi 評(píng)論0 收藏0
  • 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ā)指南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元查看
<