亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

SpringBoot?LiteFlow引擎框架使用原理解析

 更新時間:2024年03月05日 15:13:06   作者:程序猿進(jìn)階  
LiteFlow是一個輕量且強(qiáng)大的國產(chǎn)規(guī)則引擎框架,可用于復(fù)雜的組件化業(yè)務(wù)的編排領(lǐng)域,本文給大家介紹SpringBoot?LiteFlow引擎框架的相關(guān)操作,感興趣的朋友跟隨小編一起看看吧

一、LiteFlow 簡介

LiteFlow是一個輕量且強(qiáng)大的國產(chǎn)規(guī)則引擎框架,可用于復(fù)雜的組件化業(yè)務(wù)的編排領(lǐng)域。幫助系統(tǒng)變得更加絲滑且靈活。利用LiteFlow,你可以將瀑布流式的代碼,轉(zhuǎn)變成以組件為核心概念的代碼結(jié)構(gòu),這種結(jié)構(gòu)的好處是可以任意編排,組件與組件之間是解耦的,組件可以用腳本來定義,組件之間的流轉(zhuǎn)全靠規(guī)則來驅(qū)動。LiteFlow擁有開源規(guī)則引擎最為簡單的DSL語法。 LiteFlow官網(wǎng)

LiteFlow2020年正式開源,2021年獲得開源中國年度最受歡迎開源軟件殊榮。于2022年獲得Gitee最有價值開源項目GVP榮譽(yù)。是一個正處在高速發(fā)展中的開源項目。LiteFlow是一個由社區(qū)驅(qū)動的項目,擁有一個2500多人的使用者社區(qū)。雖然相比AcitivitiFlowable來說,LiteFlow的知名度要低得多,功能也沒有這些知名成熟引擎那么強(qiáng)大,但LiteFlow還是有諸多優(yōu)點,能夠滿足你絕大部分的場景。這些優(yōu)點包括:
【1】規(guī)則多樣化: 規(guī)則支持xmljson、yml三種規(guī)則文件寫法方式。
【2】使用便捷: 引幾個jar包、實現(xiàn)幾個接口、寫一個流程編排文件,就能運行。
【3】編排豐富: 支持串行、并行、選擇、循環(huán)、異常處理、嵌套等各種編排方式。
【4】事件監(jiān)聽: 支持事件觸發(fā)和狀態(tài)變化監(jiān)聽,可以方便地擴(kuò)展和定制工作流處理邏輯。
【5】異步超時: 支持異步執(zhí)行和超時控制,可以提高系統(tǒng)的并發(fā)處理能力和穩(wěn)定性。
【6】支持腳本: 支持各種主流腳本語言。
【7】配置源豐富: 支持將流程定義放到ZK/DB/Etcd/Nacos/Redis/Apollo和自定義擴(kuò)展等。相當(dāng)于可以實現(xiàn)動態(tài)配置更改。
【8】定制化: 高度可定制化,用戶可以根據(jù)自己的需求自由擴(kuò)展和定制LiteFlow的各種組件和功能。
【9】支持眾多腳本語言: LiteFlow的腳本組件,支持眾多腳本語言Groovy/JavaScript/QLExpress/Python/Lua/Aviator/Java,完全和Java打通,你可以用腳本來實現(xiàn)任何邏輯。
【10】優(yōu)雅熱刷新機(jī)制: 規(guī)則變化,無需重啟您的應(yīng)用,即時改變應(yīng)用的規(guī)則。高并發(fā)下不會因為刷新規(guī)則導(dǎo)致正在執(zhí)行的規(guī)則有任何錯亂。
【11】支持廣泛: 不管你的項目是不是基于Springboot,Spring還是任何其他java框架構(gòu)建,LiteFlow都能游刃有余。
【12】上下文隔離機(jī)制: 可靠的上下文隔離機(jī)制,你無需擔(dān)心高并發(fā)情況下的數(shù)據(jù)串流。
【13】性能卓越: 框架本身幾乎不消耗額外性能,性能取決你的組件執(zhí)行效率。
【14】自帶簡單監(jiān)控: 框架內(nèi)自帶一個命令行的監(jiān)控,能夠知道每個組件的運行耗時排行。

適合使用的這項技術(shù)的系統(tǒng)

在每個公司的系統(tǒng)中,總有一些擁有復(fù)雜業(yè)務(wù)邏輯的系統(tǒng),這些系統(tǒng)承載著核心業(yè)務(wù)邏輯,幾乎每個需求都和這些核心業(yè)務(wù)有關(guān),這些核心業(yè)務(wù)業(yè)務(wù)邏輯冗長,涉及內(nèi)部邏輯運算,緩存操作,持久化操作,外部資源調(diào)取,內(nèi)部其他系統(tǒng)RPC調(diào)用等等。時間一長,項目幾經(jīng)易手,維護(hù)成本就會越來越高。各種硬代碼判斷,分支條件越來越多。代碼的抽象,復(fù)用率也越來越低,各個模塊之間的耦合度很高。一小段邏輯的變動,會影響到其他模塊,需要進(jìn)行完整回歸測試來驗證。如要靈活改變業(yè)務(wù)流程的順序,則要進(jìn)行代碼大改動進(jìn)行抽象,重新寫方法。實時熱變更業(yè)務(wù)流程,幾乎很難實現(xiàn)。

如何打破僵局?LiteFlow為解耦邏輯而生,為編排而生,在使用LiteFlow之后,你會發(fā)現(xiàn)打造一個低耦合,靈活的系統(tǒng)會變得易如反掌!

二、LiteFlow 原理

如果你要對復(fù)雜業(yè)務(wù)邏輯進(jìn)行新寫或者重構(gòu),用LiteFlow最合適不過。它是一個編排式的規(guī)則引擎框架,組件編排,幫助解耦業(yè)務(wù)代碼,讓每一個業(yè)務(wù)片段都是一個組件。

LiteFlow的核心是“流程即代碼”,即將業(yè)務(wù)流程和代碼結(jié)構(gòu)緊密耦合在一起。LiteFlow采用基于XML文件的流程定義方式,通過定義流程節(jié)點和連線來描述整個工作流程。每個流程節(jié)點都對應(yīng)著Java代碼中的一個方法,而連線則對應(yīng)著方法之間的調(diào)用關(guān)系。這樣一來,我們就可以非常直觀地看到整個業(yè)務(wù)流程的處理過程,而且在修改流程時也更加方便快捷。

組件可實時熱更替,也可以給編排好的邏輯流里實時增加一個組件,從而改變你的業(yè)務(wù)邏輯。

編排語法強(qiáng)大到可以編排出任何你想要的邏輯流程例如:

三、使用場景

LiteFlow適用于哪些場景: LiteFlow適用于擁有復(fù)雜邏輯的業(yè)務(wù),比如說價格引擎,下單流程等,這些業(yè)務(wù)往往都擁有很多步驟,這些步驟完全可以按照業(yè)務(wù)粒度拆分成一個個獨立的組件,進(jìn)行裝配復(fù)用變更。使用LiteFlow,你會得到一個靈活度高,擴(kuò)展性很強(qiáng)的系統(tǒng)。因為組件之間相互獨立,也可以避免改一處而動全身的這樣的風(fēng)險。

LiteFlow不適用于哪些場景: LiteFlow不適合角色任務(wù)之間的流轉(zhuǎn),類似于審批流,A審批完應(yīng)該是B審批,然后再流轉(zhuǎn)到C角色。這里申明下,LiteFlow只做基于邏輯的流轉(zhuǎn),而不做基于角色任務(wù)的流轉(zhuǎn)。如果你想做基于角色任務(wù)的流轉(zhuǎn),推薦使用flowable,activiti這2個框架。

四、JDK支持情況

LiteFlow要求的最低的JDK版本為8,支持JDK8~JDK17所有的版本。如果你使用JDK11以上,確保LiteFlow的版本為v2.10.6及其以上版本。因為LiteFlowv2.10.6開始,對JDK11JDK17進(jìn)行了詳細(xì)的用例測試,通過了全部的900多個測試用例。而在v2.10.6以下版本,在JDK11以上是未經(jīng)過測試用例保障的。特別需要注意的是,如果你使用JDK11及其以上的版本,請確保jvm參數(shù)加上以下參數(shù):

--add-opens java.base/sun.reflect.annotation=ALL-UNNAMED

五、Springboot 整合流程

LiteFlow要求的Springboot的最低的版本是2.0。支持的范圍是Springboot 2.X ~ Springboot 3.X。如果你使用了最新的Springboot 3.X,相應(yīng)的JDK版本也要切換為JDK17。

LiteFlow提供了liteflow-spring-boot-starter依賴包,提供自動裝配功能

<dependency>
    <groupId>com.yomahub</groupId>
    <artifactId>liteflow-spring-boot-starter</artifactId>
    <version>2.11.3</version>
</dependency>

組件定義

在依賴了以上jar包后,你需要定義并實現(xiàn)一些組件,確保SpringBoot會掃描到這些組件并注冊進(jìn)上下文。

@Component("a")
public class ACmp extends NodeComponent {
	@Override
	public void process() {
		//do your business
	}
}

以此類推再分別定義b,c組件:

@Component("b")
public class BCmp extends NodeComponent {
	@Override
	public void process() {
		//do your business
	}
}
@Component("c")
public class CCmp extends NodeComponent {
	@Override
	public void process() {
		//do your business
	}
}

SpringBoot配置文件

然后,在你的SpringBootapplication.properties或者application.yml里添加配置(這里以yaml為例,properties也是一樣的)

liteflow:
  #規(guī)則文件路徑
  rule-source: config/flow.el.xml
  #-----------------以下非必須-----------------
  #liteflow是否開啟,默認(rèn)為true
  enable: true
  #liteflow的banner打印是否開啟,默認(rèn)為true
  print-banner: true
  #zkNode的節(jié)點,只有使用zk作為配置源的時候才起作用,默認(rèn)為/lite-flow/flow
  zk-node: /lite-flow/flow
  #上下文的最大數(shù)量槽,默認(rèn)值為1024
  slot-size: 1024
  #FlowExecutor的execute2Future的線程數(shù),默認(rèn)為64
  main-executor-works: 64
  #FlowExecutor的execute2Future的自定義線程池Builder,LiteFlow提供了默認(rèn)的Builder
  main-executor-class: com.yomahub.liteflow.thread.LiteFlowDefaultMainExecutorBuilder
  #自定義請求ID的生成類,LiteFlow提供了默認(rèn)的生成類
  request-id-generator-class: com.yomahub.liteflow.flow.id.DefaultRequestIdGenerator
  #并行節(jié)點的線程池Builder,LiteFlow提供了默認(rèn)的Builder
  thread-executor-class: com.yomahub.liteflow.thread.LiteFlowDefaultWhenExecutorBuilder
  #異步線程最長的等待時間(只用于when),默認(rèn)值為15000
  when-max-wait-time: 15000
  #異步線程最長的等待時間(只用于when),默認(rèn)值為MILLISECONDS,毫秒
  when-max-wait-time-unit: MILLISECONDS
  #when節(jié)點全局異步線程池最大線程數(shù),默認(rèn)為16
  when-max-workers: 16
  #并行循環(huán)子項線程池最大線程數(shù),默認(rèn)為16
  parallelLoop-max-workers: 16
  #并行循環(huán)子項線程池等待隊列數(shù),默認(rèn)為512
  parallelLoop-queue-limit: 512
  #并行循環(huán)子項的線程池Builder,LiteFlow提供了默認(rèn)的Builder
  parallelLoop-executor-class: com.yomahub.liteflow.thread.LiteFlowDefaultParallelLoopExecutorBuilder
  #when節(jié)點全局異步線程池等待隊列數(shù),默認(rèn)為512
  when-queue-limit: 512
  #是否在啟動的時候就解析規(guī)則,默認(rèn)為true
  parse-on-start: true
  #全局重試次數(shù),默認(rèn)為0
  retry-count: 0
  #是否支持不同類型的加載方式混用,默認(rèn)為false
  support-multiple-type: false
  #全局默認(rèn)節(jié)點執(zhí)行器
  node-executor-class: com.yomahub.liteflow.flow.executor.DefaultNodeExecutor
  #是否打印執(zhí)行中過程中的日志,默認(rèn)為true
  print-execution-log: true
  #是否開啟本地文件監(jiān)聽,默認(rèn)為false
  enable-monitor-file: false
  #簡易監(jiān)控配置選項
  monitor:
    #監(jiān)控是否開啟,默認(rèn)不開啟
    enable-log: false
    #監(jiān)控隊列存儲大小,默認(rèn)值為200
    queue-limit: 200
    #監(jiān)控一開始延遲多少執(zhí)行,默認(rèn)值為300000毫秒,也就是5分鐘
    delay: 300000
    #監(jiān)控日志打印每過多少時間執(zhí)行一次,默認(rèn)值為300000毫秒,也就是5分鐘
    period: 300000

規(guī)則文件的定義

同時,你得在resources下的config/flow.el.xml中定義規(guī)則:SpringBoot在啟動時會自動裝載規(guī)則文件。

<?xml version="1.0" encoding="UTF-8"?>
<flow>
    <chain name="chain1">
        THEN(a, b, c);
    </chain>
</flow>

執(zhí)行

聲明啟動類:

@SpringBootApplication
//把你定義的組件掃入Spring上下文中
@ComponentScan({"com.xxx.xxx.cmp"})
public class LiteflowExampleApplication {
    public static void main(String[] args) {
        SpringApplication.run(LiteflowExampleApplication.class, args);
    }
}

然后你就可以在Springboot任意被Spring托管的類中拿到flowExecutor,進(jìn)行執(zhí)行鏈路:這個DefaultContext是默認(rèn)的上下文,用戶可以用最自己的任意Bean當(dāng)做上下文傳入,如果需要傳入自己的上下文,則需要傳用戶BeanClass屬性

@Component
public class YourClass{
    @Resource
    private FlowExecutor flowExecutor;
    public void testConfig(){
        LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
    }
}

六、數(shù)據(jù)上下文

在執(zhí)行器執(zhí)行流程時會分配數(shù)據(jù)上下文實例給這個請求。不同請求的數(shù)據(jù)上下文實例是完全隔離的。里面存放著此請求所有的用戶數(shù)據(jù)。不同的組件之間是不傳遞參數(shù)的,所有的數(shù)據(jù)交互都是通過這個數(shù)據(jù)上下文來實現(xiàn)的。數(shù)據(jù)上下文這個概念在LiteFlow框架中非常重要,你所有的業(yè)務(wù)數(shù)據(jù)都是放在數(shù)據(jù)上下文中。要做到可編排,一定是消除每個組件差異性的。如果每個組件出參入?yún)⒍疾灰恢?,那就沒法編排了。

LiteFlow對此有獨特的設(shè)計理念,平時我們寫瀑布流的程序時,A調(diào)用B,那A一定要把B所需要的參數(shù)傳遞給B,而在LiteFlow框架體系中,每個組件的定義中是不需要接受參數(shù)的,也無任何返回的。每個組件只需要從數(shù)據(jù)上下文中獲取自己關(guān)心的數(shù)據(jù)即可,而不用關(guān)心此數(shù)據(jù)是由誰提供的,同樣的,每個組件也只要把自己執(zhí)行所產(chǎn)生的結(jié)果數(shù)據(jù)放到數(shù)據(jù)上下文中即可,也不用關(guān)心此數(shù)據(jù)到底是提供給誰用的。這樣一來,就從數(shù)據(jù)層面一定程度的解耦了。從而達(dá)到可編排的目的。關(guān)于這個理念,也在LiteFlow簡介中的設(shè)計原則有提到過,給了一個形象的例子,大家可以再去看看。

一旦在數(shù)據(jù)上下文中放入數(shù)據(jù),整個鏈路中的任一節(jié)點都是可以取到的。

默認(rèn)上下文

LiteFlow提供了一個默認(rèn)的數(shù)據(jù)上下文的實現(xiàn):DefaultContext。這個默認(rèn)的實現(xiàn)其實里面主要存儲數(shù)據(jù)的容器就是一個Map。你可以通過DefaultContext中的setData方法放入數(shù)據(jù),通過getData方法獲得數(shù)據(jù)。

::: warning
DefaultContext雖然可以用,但是在實際業(yè)務(wù)中,用這個會存在大量的弱類型,存取數(shù)據(jù)的時候都要進(jìn)行強(qiáng)轉(zhuǎn),頗為不方便。所以官方建議你自己去實現(xiàn)自己的數(shù)據(jù)上下文。
:::

自定義上下文

在一個流程中,總會有一些初始的參數(shù),比如訂單號,用戶Id等等一些的初始參數(shù)。這時候需要通過以下方法的第二個參數(shù)傳入:

//參數(shù)為流程ID,無初始流程入?yún)?,上下文類型為默認(rèn)的DefaultContext
public LiteflowResponse execute2Resp(String chainId)
//第一個參數(shù)為流程ID,第二個參數(shù)為流程入?yún)?。上下文類型為默認(rèn)的DefaultContext
public LiteflowResponse execute2Resp(String chainId, Object param);
//第一個參數(shù)為流程ID,第二個參數(shù)為流程入?yún)ⅲ竺婵梢詡魅攵鄠€上下文class
public LiteflowResponse execute2Resp(String chainId, Object param, Class<?>... contextBeanClazzArray)
//第一個參數(shù)為流程ID,第二個參數(shù)為流程入?yún)ⅲ竺婵梢詡魅攵鄠€上下文的Bean
public LiteflowResponse execute2Resp(String chainId, Object param, Object... contextBeanArray)

你可以用你自己的任意的Bean當(dāng)做上下文進(jìn)行傳入。LiteFlow對上下文的Bean沒有任何要求。自己定義的上下文實質(zhì)上就是一個最簡單的值對象,自己定義的上下文因為是強(qiáng)類型,更加貼合業(yè)務(wù)。你可以像這樣進(jìn)行傳入:

LiteflowResponse response = flowExecutor.execute2Resp("chain1", 流程初始參數(shù), CustomContext.class);

傳入之后,LiteFlow會在調(diào)用時進(jìn)行初始化,給這個上下文分配唯一的實例。你在組件之中可以這樣去獲得這個上下文實例:

@LiteflowComponent("yourCmpId")
public class YourCmp extends NodeComponent {
	@Override
	public void process() {
		OrderContext orderContext = this.getContextBean(OrderContext.class);
		UserContext userContext = this.getContextBean(UserContext.class);
		SignContext signContext = this.getContextBean(SignContext.class);
		//如果你只想獲取第一個上下文,第一個上下文是OrderContext,那么也可以用這個方法
		//OrderContext orderContext = this.getFirstContextBean();
		...
	}
}

多上下文

LiteFlow在新版本中支持了多上下文,在執(zhí)行的時候同時初始化你傳入的多個上下文。在組件里也可以根據(jù)class類型很方便的拿到。你可以像這樣進(jìn)行傳入:

LiteflowResponse response = flowExecutor.execute2Resp("chain1", 流程初始參數(shù), OrderContext.class, UserContext.class, SignContext.class);

在組件之中可以這樣去獲得這個上下文實例:

@LiteflowComponent("yourCmpId")
public class YourCmp extends NodeComponent {
	@Override
	public void process() {
		OrderContext orderContext = this.getContextBean(OrderContext.class);
		UserContext userContext = this.getContextBean(UserContext.class);
		SignContext signContext = this.getContextBean(SignContext.class);
		//如果你只想獲取第一個上下文,第一個上下文是OrderContext,那么也可以用這個方法
		//OrderContext orderContext = this.getFirstContextBean();
		...
	}
}

用初始化好的上下文傳入

LiteFlow2.8.4版本開始,允許用戶傳入一個或多個已經(jīng)初始化好的bean作為上下文,而不是傳入class對象。在拿到FlowExecutor之后,你可以像如下一樣,傳入已經(jīng)初始化好的bean作為上下文(當(dāng)然也支持多上下文,這里只演示單上下文):

OrderContext orderContext = new OrderContext();
orderContext.setOrderNo("SO11223344");
LiteflowResponse response = flowExecutor.execute2Resp("chain1", null, orderContext);

::: warning
框架并不支持上下文beanclass混傳,你要么都傳bean,要么都傳class。
:::

七、異步Future

public Future<LiteflowResponse> execute2Future(String chainId, Object param, Class<?>... contextBeanClazzArray)

如果調(diào)用這個方法,那就是無阻塞的,想要拿到response,請用得到的future.get()就可以了。同時,主執(zhí)行器在這個模式下的線程數(shù)和線程池也可以自定義,具體配置如下,LiteFlow已經(jīng)設(shè)置了預(yù)設(shè)值,你也可自己定義。

liteflow.main-executor-works=64
liteflow.main-executor-class=com.yomahub.liteflow.thread.LiteFlowDefaultMainExecutorBuilder

如果你定義了自定義線程池,你需新建一個類,然后實現(xiàn)ExecutorBuilder接口:

public class CustomThreadBuilder implements ExecutorBuilder {
    @Override
    public ExecutorService buildExecutor() {
        return Executors.newCachedThreadPool();
    }
}

八、規(guī)則寫法 串行編排

如果你要依次執(zhí)行a,b,c,d四個組件,你可以用THEN關(guān)鍵字,需要注意的是,THEN必須大寫。

<chain name="chain1">
    THEN(a, b, c, d);
</chain>

并行編排

如果你要并行執(zhí)行a,b,c三個組件,你可以用WHEN關(guān)鍵字,需要注意的是,WHEN必須大寫。

<chain name="chain1">
    WHEN(a, b, c);
</chain>

和串行嵌套起來:讓我們把THEN和WHEN結(jié)合起來用,看一個示例:b,c,d默認(rèn)并行都執(zhí)行完畢后,才會執(zhí)行e。

<chain name="chain1">
    THEN(
        a,
        WHEN(b, c, d),
        e
    );
</chain>

上面的示例應(yīng)該很好理解吧,那么再看一個示例:

<chain name="chain1">
    THEN(
        a,
        WHEN(b, THEN(c, d)),
        e
    );
</chain>

忽略錯誤: WHEN關(guān)鍵字提供了一個子關(guān)鍵字ignoreError(默認(rèn)為`false``)來提供忽略錯誤的特性,用法如下:

<chain name="chain1">
    THEN(
        a,
        WHEN(b, c, d).ignoreError(true),
        e
    );
</chain>

設(shè)b,c,d中任一一個節(jié)點有異常,那么最終e仍舊會被執(zhí)行。

任一節(jié)點先執(zhí)行完則忽略其他: WHEN關(guān)鍵字提供了一個子關(guān)鍵字any(默認(rèn)為false)用來提供并行流程中,任一條分支先執(zhí)行完即忽略其他分支,繼續(xù)執(zhí)行的特性。用法如下:假設(shè)e節(jié)點先執(zhí)行完,那么不管其他分支是否執(zhí)行完,會立馬執(zhí)行節(jié)點f

<chain name="chain1">
    THEN(
        a,
        WHEN(b, THEN(c, d), e).any(true),
        f
    );
</chain>

指定任意節(jié)點先執(zhí)行完則忽略其他: LiteFlowv2.11.1開始,支持了并行編排中指定節(jié)點的執(zhí)行則忽略其他,WHEN關(guān)鍵字新增子關(guān)鍵字must(不可為空),可用于指定需等待執(zhí)行的任意節(jié)點,可以為1個或者多個,若指定的所有節(jié)點率先完成,則繼續(xù)往下執(zhí)行,忽略同級別的其他任務(wù),用法如下:must指定了b,c,則b,c是一定會被執(zhí)行完畢了,如果b,c執(zhí)行完畢了后d還未執(zhí)行完,則忽略,直接執(zhí)行下一個組件f

<chain name="chain1">
    THEN(
        a,
        WHEN(b, c, d).must(b, c),
        f
    );
</chain>

以上是單節(jié)點的用法,must還可以指定一個或多個表達(dá)式。比如:WHEN里有一個嵌套的THEN,如果需要指定這個表達(dá)式,則需要給這個表達(dá)式設(shè)置一個id,must里需要指定這個id,需要注意的是,must里指定id,需要用引號括起來。

<chain name="chain1">
    THEN(
        a,
        WHEN(b, THEN(c, d).id("t1"), e).must(b, "t1"),
        f
    );
</chain>

開啟WHEN線程池隔離:
目前liteflow設(shè)計里when線程池,如果你不單獨設(shè)置自定義線程池,那么就會用默認(rèn)的線程池。而這個線程池,是所有的when共同一個。LiteFlow從2.11.1開始,提供一個liteflow.when-thread-pool-isolate參數(shù),默認(rèn)為false,如果設(shè)為true,則會開啟WHEN的線程池隔離機(jī)制,這意味著每一個when都會有單獨的線程池。這個特性對于運行復(fù)雜的嵌套when時是可以提升運行速度的且規(guī)避掉一些鎖的問題。

你可以如下配置來開啟:

liteflow.when-thread-pool-isolate=true

選擇編排

我們在寫業(yè)務(wù)邏輯的時候,通常會碰到選擇性問題,即,如果返回結(jié)果1,則進(jìn)入A流程,如果返回結(jié)果2,則進(jìn)入B流程,如果返回結(jié)果3,則進(jìn)入C流程。在有些流程定義中也被定義為排他網(wǎng)關(guān)。這個通過LiteFLow的表達(dá)式也非常容易實現(xiàn),你可以用SWITCH...TO的組合關(guān)鍵字,注意的是SWITCH必須大寫,to大小寫均可。

如果,根據(jù)組件a,來選擇執(zhí)行b,c,d中的一個,你可以如下聲明:

在這里插入圖片描述

@LiteflowComponent("a")
public class ACmp extends NodeSwitchComponent {
    @Override
    public String processSwitch() throws Exception {
        System.out.println("Acomp executed!");
        return "c";
    }
}

DEFAULT關(guān)鍵字: LiteFlow2.9.5開始,對選擇編排新增了一個DEFAULT關(guān)鍵字。用法為SWITCH...TO...DEFAULT。比如如下表達(dá)式:

<chain name="chain1">
    SWITCH(x).TO(a, b, c).DEFAULT(y);
</chain>

如上表達(dá)式的x如果返回非a,b,c中的一個,則默認(rèn)選擇到y。當(dāng)然DEFAULT里面也可以是一個表達(dá)式。

選擇編排中的id語法: 接下來展示一個SWITCH中套THENWHEN的例子。如果你閱讀過選擇組件這一章,就應(yīng)該知道,LiteFlow通過選擇組件的返回來確定該選擇什么。那么如果SWITCH中套一個THEN,那么選擇組件如果要選擇這個THEN應(yīng)該返回什么呢?LiteFlow中規(guī)定,每個表達(dá)式都可以有一個id值,你可以設(shè)置id值來設(shè)置一個表達(dá)式的id值。然后在選擇組件里返回這個id即可。用法如下:

<chain name="chain1">
    THEN(
        a,
        SWITCH(b).to(
            c, 
            THEN(d, e).id("t1")
        ),
        f
    );
</chain>

如果你想選擇THEN這個表達(dá)式,那么你可以在選擇節(jié)點里返回t1:

@LiteflowComponent("b")
public class BCmp extends NodeSwitchComponent {
    @Override
    public String processSwitch() throws Exception {
        //do your biz
        return "t1";
    }
}

選擇編排中的tag語法: 事實上,除了給表達(dá)式賦值id屬性之外,你還可以給表達(dá)式賦值tag屬性。用法如下:

<chain name="chain1">
    THEN(
        a,
        SWITCH(b).to(
            c, 
            THEN(d, e).tag("t1")
        ),
        f
    );
</chain>

如果你想選擇THEN這個表達(dá)式,那么你可以在選擇節(jié)點里返回:

@LiteflowComponent("b")
public class BCmp extends NodeSwitchComponent {
    @Override
    public String processSwitch() throws Exception {
        return "tag:t1";
        //以下這種也是可以的
        return ":t1";
    }
}

條件編排

條件編排是選擇編排一個變種,選擇編排是根據(jù)邏輯去選擇多個子項中的一項。而條件編排只有真和假2個子項,這處理某些業(yè)務(wù)的過程中非常有用。其實簡單來說,條件編排就是編程語言中的if else。只不過在LiteFlow EL語法中有一些不一樣的用法。以下IFELIF的第一個參數(shù)要求定義條件組件。

IF的二元表達(dá)式: 其中x為條件節(jié)點,為真的情況下,執(zhí)行鏈路就為x->a->b,為假鏈路就為x->b。

<chain name="chain1">
    THEN(
        IF(x, a),
        b
    );
</chain>

@Component("x")
public class XCmp extends NodeIfComponent {
	@Override
	public boolean processIf() throws Exception {
	    //do your biz
		return true;
	}
}

IF的三元表達(dá)式: 其中x為條件節(jié)點,為真的情況下,執(zhí)行鏈路就為x->a->c,為假鏈路就為x->b->c。

<chain name="chain1">
    THEN(
        IF(x, a, b),
        c
    );
</chain>

ELIF表達(dá)式: ELIF關(guān)鍵字的用法其實和java語言的else if類似,可以跟多個,和IF二元表達(dá)式參數(shù)一樣,一般最后還會跟個ELSE,用于多重條件的判斷:

<chain name="chain1">
    IF(x1, a).ELIF(x2, b).ELIF(x3, c).ELIF(x4, d).ELSE(THEN(m, n));
</chain>

循環(huán)編排

FOR循環(huán): FOR循環(huán)表達(dá)式用于固定次數(shù)的循環(huán),通常的用法為:

<chain name="chain1">
    FOR(5).DO(THEN(a, b));
</chain>

上述表達(dá)式表示把a->b這個鏈路固定循環(huán)了5次。如果你在定義規(guī)則的時候并不確定要循環(huán)幾次,要在代碼運行的時候才知道。那你也可以這樣定義:

<chain name="chain1">
    FOR(f).DO(THEN(a, b));
</chain>

其中f這個節(jié)點需要為次數(shù)循環(huán)組件,返回一個int循環(huán)次數(shù),f節(jié)點的定義,需要繼承NodeForComponent,需要實現(xiàn)processFor方法:

@LiteflowComponent("f")
public class FCmp extends NodeForComponent {
    @Override
    public int processFor() throws Exception {
        //這里根據(jù)業(yè)務(wù)去返回for的結(jié)果
    }
}

循環(huán)下標(biāo)獲?。宏P(guān)鍵字FOR...DO...DO里面的任意java組件都可以通過this.getLoopIndex()來獲得下標(biāo)。在腳本中通過_meta.loopIndex來獲取。

WHILE循環(huán):

<chain name="chain1">
    WHILE(w).DO(THEN(a, b));
</chain>

其中w這個節(jié)點需要為條件循環(huán)組件,返回一個布爾值,為true則繼續(xù)循環(huán)

@LiteflowComponent("w")
public class WCmp extends NodeWhileComponent {
    @Override
    public boolean processWhile() throws Exception {
        //這里根據(jù)業(yè)務(wù)去返回while的結(jié)果
    }
}

循環(huán)下標(biāo)獲?。宏P(guān)鍵字WHILE...DO...DO里面的任意節(jié)點都可以通過this.getLoopIndex()來獲得下標(biāo)。在腳本中通過_meta.loopIndex來獲取。

ITERATOR迭代循環(huán)

<chain name="chain1">
    ITERATOR(x).DO(THEN(a, b));
</chain>

其中x這個節(jié)點需要為迭代循環(huán)組件,返回一個迭代器:x節(jié)點的定義,需要繼承NodeIteratorComponent,需要實現(xiàn)processIterator方法:

@LiteflowComponent("x")
public class XCmp extends NodeIteratorComponent {
    @Override
    public Iterator<?> processIterator() throws Exception {
        List<String> list = ListUtil.toList("jack", "mary", "tom");
        return list.iterator();
    }
}

BREAK

LiteFlow同樣也支持BREAK語法,代表退出循環(huán)。BREAK關(guān)鍵字可以跟在FORWHILE后面,通常用法為:

<chain name="chain1">
    FOR(f).DO(THEN(a, b)).BREAK(c);
</chain>
<chain name="chain1">
    WHILE(w).DO(THEN(a, b)).BREAK(c);
</chain>

其中c這個節(jié)點需要為退出循環(huán)組件,返回一個布爾值,為true則退出循環(huán)。c節(jié)點的定義,需要繼承NodeBreakComponent,需要實現(xiàn)processBreak方法:

@LiteflowComponent("c")
public class CCmp extends NodeBreakComponent {
    @Override
    public boolean processBreak() throws Exception {
        //這里根據(jù)業(yè)務(wù)去返回break的結(jié)果
    }
}

BREAK關(guān)鍵字是在每次循環(huán)的末尾進(jìn)行判斷的。

到此這篇關(guān)于SpringBoot——LiteFlow引擎框架的文章就介紹到這了,更多相關(guān)SpringBoot LiteFlow引擎內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • elasticsearch 8.2.3 安裝及springboot簡單使用

    elasticsearch 8.2.3 安裝及springboot簡單使用

    這篇文章主要介紹了elasticsearch 8.2.3 安裝及springboot簡單使用,本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-06-06
  • 關(guān)于Idea中的.properties文件顯示問題

    關(guān)于Idea中的.properties文件顯示問題

    這篇文章主要介紹了關(guān)于Idea中的.properties文件顯示問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • Spring Boot 與 Kotlin 使用JdbcTemplate連接MySQL數(shù)據(jù)庫的方法

    Spring Boot 與 Kotlin 使用JdbcTemplate連接MySQL數(shù)據(jù)庫的方法

    本文介紹在Spring Boot基礎(chǔ)下配置數(shù)據(jù)源和通過 JdbcTemplate 編寫數(shù)據(jù)訪問的示例。感興趣的朋友跟隨腳本之家小編一起學(xué)習(xí)吧
    2018-01-01
  • 如何使用Java操作Zookeeper

    如何使用Java操作Zookeeper

    這篇文章主要介紹了如何使用Java操作Zookeeper,幫助大家更好的理解和學(xué)習(xí)使用Java,感興趣的朋友可以了解下
    2021-04-04
  • Java基本知識點之變量和數(shù)據(jù)類型

    Java基本知識點之變量和數(shù)據(jù)類型

    這篇文章主要給大家介紹了關(guān)于Java基本知識點之變量和數(shù)據(jù)類型的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • 詳解將Eclipse代碼導(dǎo)入到AndroidStudio的兩種方式

    詳解將Eclipse代碼導(dǎo)入到AndroidStudio的兩種方式

    本篇文章主要介紹了詳解將Eclipse代碼導(dǎo)入到AndroidStudio的兩種方式,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-12-12
  • Java日期時間處理問題(從Date、Calendar到SimpleDateFormat)

    Java日期時間處理問題(從Date、Calendar到SimpleDateFormat)

    這篇文章主要介紹了Java日期時間處理深度解析(從Date、Calendar到SimpleDateFormat),我們詳細(xì)討論了Java中的日期和時間處理,包括Date、Calendar和SimpleDateFormat類的使用,以及Java?8引入的新的日期時間API的優(yōu)勢,需要的朋友可以參考下
    2024-08-08
  • java并發(fā)編程專題(十一)----(JUC原子類)數(shù)組類型詳解

    java并發(fā)編程專題(十一)----(JUC原子類)數(shù)組類型詳解

    這篇文章主要介紹了JAVA JUC原子類 數(shù)組類型詳解的相關(guān)資料,文中示例代碼非常詳細(xì),幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-07-07
  • SpringAOP實現(xiàn)登錄驗證的操作代碼

    SpringAOP實現(xiàn)登錄驗證的操作代碼

    這篇文章主要介紹了SpringAOP實現(xiàn)登錄驗證功能,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-01-01
  • java學(xué)生信息管理系統(tǒng)源代碼

    java學(xué)生信息管理系統(tǒng)源代碼

    這篇文章主要為大家詳細(xì)介紹了java學(xué)生信息管理系統(tǒng)源代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-01-01

最新評論