環(huán)境:SpringBoot2.7.16
LiteFlow是一個(gè)非常強(qiáng)大的現(xiàn)代化的規(guī)則引擎框架,融合了編排特性和規(guī)則引擎的所有特性。
在每個(gè)公司的系統(tǒng)中,總有一些擁有復(fù)雜業(yè)務(wù)邏輯的系統(tǒng),這些系統(tǒng)承載著核心業(yè)務(wù)邏輯,幾乎每個(gè)需求都和這些核心業(yè)務(wù)有關(guān),這些核心業(yè)務(wù)業(yè)務(wù)邏輯冗長(zhǎng),涉及內(nèi)部邏輯運(yùn)算,緩存操作,持久化操作,外部資源調(diào)取,內(nèi)部其他系統(tǒng)RPC調(diào)用等等。時(shí)間一長(zhǎng),項(xiàng)目幾經(jīng)易手,維護(hù)成本就會(huì)越來(lái)越高。各種硬代碼判斷,分支條件越來(lái)越多。代碼的抽象,復(fù)用率也越來(lái)越低,各個(gè)模塊之間的耦合度很高。一小段邏輯的變動(dòng),會(huì)影響到其他模塊,需要進(jìn)行完整回歸測(cè)試來(lái)驗(yàn)證。如要靈活改變業(yè)務(wù)流程的順序,則要進(jìn)行代碼大改動(dòng)進(jìn)行抽象,重新寫(xiě)方法。實(shí)時(shí)熱變更業(yè)務(wù)流程,幾乎很難實(shí)現(xiàn)。LiteFlow為解耦邏輯而生,為編排而生,在使用LiteFlow之后,你會(huì)發(fā)現(xiàn)打造一個(gè)低耦合,靈活的系統(tǒng)會(huì)變得易如反掌!
利用LiteFlow,你可以將瀑布流式的代碼,轉(zhuǎn)變成以組件為核心概念的代碼結(jié)構(gòu),這種結(jié)構(gòu)的好處是可以任意編排,組件與組件之間是解耦的,組件可以用腳本來(lái)定義,組件之間的流轉(zhuǎn)全靠規(guī)則來(lái)驅(qū)動(dòng)。LiteFlow擁有開(kāi)源規(guī)則引擎最為簡(jiǎn)單的DSL語(yǔ)法。十分鐘就可上手。
圖片
組件可實(shí)時(shí)熱更替,也可以給編排好的邏輯流里實(shí)時(shí)增加一個(gè)組件,從而改變你的業(yè)務(wù)邏輯。
圖片
LiteFlow的腳本組件,支持眾多腳本語(yǔ)言,完全和Java打通,你可以用腳本來(lái)實(shí)現(xiàn)任何邏輯。
圖片
LiteFlow支持把編排規(guī)則和腳本放在數(shù)據(jù)庫(kù),注冊(cè)中心中,還有可以任意擴(kuò)展的接口,方便你定制。
圖片
LiteFlow支持你能夠想象處理的任何邏輯流程,如下流程:
圖片
圖片
LiteFlow支持3中格式的規(guī)則文件定義:XML,JSON,YML。以下是XML示例:
<?xml versinotallow="1.0" encoding="UTF-8"?><flow> <chain name="example_01"> THEN(a, b, c) </chain></flow>
THNE:串行執(zhí)行,a執(zhí)行===》執(zhí)行b===》執(zhí)行c
WHEN:并行執(zhí)行
<chain name="chain1"> WHEN(a, b, c);</chain>
SWITCH:選擇執(zhí)行
<chain name="chain1"> SWITCH(a).to(b, c, d);</chain>
圖片
IF:條件執(zhí)行
IF二元
<chain name="chain1"> THEN( IF(x, a), b );</chain>
圖片
其中x為條件節(jié)點(diǎn),為真的情況下,執(zhí)行鏈路就為x->a->b,為假鏈路就為x->b。
IF三元
<chain name="chain1"> THEN( IF(x, a, b), c );</chain>
圖片
還有其它很多的規(guī)則,這里不一一舉例,可以查看官網(wǎng)。
環(huán)境配置
<dependency> <groupId>com.yomahub</groupId> <artifactId>liteflow-spring-boot-starter</artifactId> <version>2.11.4.2</version></dependency>
配置文件
#liteflow 配置liteflow: rule-source: flows/*.el.xml
整個(gè)規(guī)則流程執(zhí)行如下
圖片
規(guī)則定義
<?xml versinotallow="1.0" encoding="UTF-8"?><flow> <chain name="processOrder"> THEN( initOrder, IF(amount, discountOrder), SWITCH(userType).to(vipDiscountOrder, normalDiscountOrder), completeOrder ) </chain></flow>
這里的initOrder,amount,discountOrder等都是具體Node接口是bean的名稱。
@Component("initOrder")public class InitOrderComponent extends NodeComponent { @Override public void process() { System.out.println("初始化訂單...") ; Order order = this.getContextBean(Order.class) ; double sum = order.getItems().stream().mapToDouble(item -> { return item.getPrice().multiply(BigDecimal.valueOf(item.getQuantity())).doubleValue() ; }).sum() ; order.setTotalAmount(BigDecimal.valueOf(sum)); }}
這里只做了計(jì)算訂單總額。
判斷訂單總額節(jié)點(diǎn)
@Component("amount")public class AmountComponent extends NodeIfComponent { @Override public boolean processIf() throws Exception { System.out.println("判斷總金額,超過(guò)100元打折") ; Order order = this.getContextBean(Order.class) ; return order.getTotalAmount().doubleValue() >= 100D ; }}
用戶類型判斷,執(zhí)行哪個(gè)節(jié)點(diǎn)
@Component("userType")public class UserTypeComponent extends NodeSwitchComponent { @Override public String processSwitch() throws Exception { User user = this.getContextBean(User.class) ; if (user.isVip()) { return "vipDiscountOrder" ; } return "normalDiscountOrder" ; }}
上面返回的是具體節(jié)點(diǎn)的beanName。
VIP折扣節(jié)點(diǎn)
@Component("vipDiscountOrder")public class VIPDiscountOrderComponent extends NodeComponent { @Override public void process() { System.out.println("VIP會(huì)員打9折") ; Order order = this.getContextBean(Order.class) ; order.setTotalAmount(order.getTotalAmount().multiply(BigDecimal.valueOf(9)).divide(BigDecimal.valueOf(10), RoundingMode.HALF_UP)) ; }}
普通會(huì)員折扣節(jié)點(diǎn)
@Component("normalDiscountOrder")public class NormalDiscountOrderComponent extends NodeComponent { @Override public void process() { System.out.println("普通會(huì)員不打折") ; }}
完成節(jié)點(diǎn)
@Component("completeOrder")public class CompleteOrderComponent extends NodeComponent { @Override public void process() throws Exception { System.out.println("訂單折扣執(zhí)行完成,最后收尾...") ; }}
以上是該規(guī)則流程的所有配置及定義。接下來(lái)進(jìn)行測(cè)試
// 直接注入該類進(jìn)行規(guī)則流程的啟動(dòng)執(zhí)行@Resourceprivate FlowExecutor flowExecutor;@Testpublic void testExample02() { Order order = new Order() ; order.setId(1L) ; order.setSno("S001") ; List<OrderItem> items = new ArrayList<>() ; items.add(new OrderItem(1L, 2, BigDecimal.valueOf(22))) ; items.add(new OrderItem(2L, 1, BigDecimal.valueOf(24.5))) ; items.add(new OrderItem(3L, 5, BigDecimal.valueOf(66.3))) ; order.setItems(items) ; User user = new User() ; user.setId(1L) ; user.setVip(false) ; LiteflowResponse response = flowExecutor.execute2Resp("processOrder", null, order, user); if (!response.isSuccess()) { Exception e = response.getCause() ; e.printStackTrace() ; } else { System.out.println("流程成功執(zhí)行...") ; System.out.println("最終應(yīng)付款:" + response.getContextBean(Order.class).getTotalAmount().doubleValue()) ; }}
控制臺(tái)將會(huì)輸出詳細(xì)的信息。
圖片
修改用戶類型后執(zhí)行
圖片
以上是本篇文章的全部?jī)?nèi)容,希望對(duì)你有所幫助。
本文鏈接:http://www.www897cc.com/showinfo-26-75360-0.html強(qiáng)烈推薦強(qiáng)大的規(guī)則引擎框架LiteFlow
聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com