苏州专业高端网站建设,WordPress 付费文章插件,更合公司网站建设,成都市双流区建设局官方网站场景
在业务开发中#xff0c;经常遇到一些串行或者并行的业务流程问题#xff0c;而业务之间不必存在相关性。
使用策略和模板模式的结合可以解决这个问题#xff0c;但是使用编码的方式会使得文件太多,
在业务的部分环节可以这样操作#xff0c;在项目角度就无法一眼洞…场景
在业务开发中经常遇到一些串行或者并行的业务流程问题而业务之间不必存在相关性。
使用策略和模板模式的结合可以解决这个问题但是使用编码的方式会使得文件太多,
在业务的部分环节可以这样操作在项目角度就无法一眼洞穿其中的环节和逻辑。
一些拥有复杂业务逻辑的系统核心业务逻辑冗长涉及内部逻辑运算缓存操作持久化操作外部资源调取内部其他系统RPC调用等等。
时间一长维护的成本就会越来越高。各种硬代码判断分支条件越来越多。代码的抽象复用率也越来越低各个模块之间的耦合度很高。
一小段逻辑的变动会影响到其他模块需要进行完整回归测试来验证。
如要灵活改变业务流程的顺序则要进行代码大改动进行抽象重新写方法。
实时热变更业务流程几乎很难实现 。
LiteFlow
LiteFlow就是为解耦复杂逻辑而生如果你要对复杂业务逻辑进行新写或者重构用LiteFlow最合适不过。
它是一个轻量快速的组件式流程引擎框架组件编排帮助解耦业务代码让每一个业务片段都是一个组件
并支持热加载规则配置实现即时修改。
使用LiteFlow你需要去把复杂的业务逻辑按代码片段拆分成一个个小组件并定义一个规则流程配置。
这样所有的组件就能按照你的规则配置去进行复杂的流转。
LiteFlow官方网站
LiteFlow
LiteFlow的Gitee地址:
liteFlow: 轻量快速稳定可编排的组件式规则引擎/流程引擎。拥有全新设计的DSL规则表达式。组件复用同步/异步编排动态编排支持超多语言脚本复杂嵌套规则热部署平滑刷新规则等等功能让你加快开发效率
LiteFlow的特点 注
博客霸道流氓气质-CSDN博客
实现
1、SpringBoot中集成LiteFlow
LiteFlow要求的Springboot的最低的版本是2.0。
支持的范围是Springboot 2.X ~ Springboot 3.X。
LiteFlow提供了liteflow-spring-boot-starter依赖包提供自动装配功能
dependencygroupIdcom.yomahub/groupIdartifactIdliteflow-spring-boot-starter/artifactIdversion2.11.4.2/version
/dependency
2、SpringBoot中配置LiteFlow
在你的SpringBoot的application.properties或者application.yml里添加配置
#liteflow规则配置文件位置
liteflow:rule-source: config/flow.el.xml
规则文件的定义
在resources下的config/flow.el.xml中定义规则
?xml version1.0 encodingUTF-8?
flowchain namechain1THEN(acmp, bcmp, ccmp);/chain
/flow
根据定义的规则需要定义并实现一些组件确保SpringBoot会扫描到这些组件并注册进上下文。
import com.yomahub.liteflow.core.NodeComponent;
import org.springframework.stereotype.Component;Component(acmp)
public class ACmp extends NodeComponent {Overridepublic void process() {//do your businessSystem.out.println(acmp执行);}
}
以此类推定义另外两个组件
import com.yomahub.liteflow.core.NodeComponent;
import org.springframework.stereotype.Component;Component(bcmp)
public class BCmp extends NodeComponent {Overridepublic void process() {//do your businessSystem.out.println(bcmp执行);}
}
import com.yomahub.liteflow.core.NodeComponent;
import org.springframework.stereotype.Component;Component(ccmp)
public class CCmp extends NodeComponent {Overridepublic void process() {//do your businessSystem.out.println(ccmp执行);}
}
更多配置项内容参考文档说明
Springboot下的配置项 | LiteFlow
liteflow:#规则文件路径rule-source: config/flow.el.xml#-----------------以下非必须-----------------#liteflow是否开启默认为trueenable: true#liteflow的banner打印是否开启默认为trueprint-banner: true#zkNode的节点只有使用zk作为配置源的时候才起作用默认为/lite-flow/flowzk-node: /lite-flow/flow#上下文的最大数量槽默认值为1024slot-size: 1024#FlowExecutor的execute2Future的线程数默认为64main-executor-works: 64#FlowExecutor的execute2Future的自定义线程池BuilderLiteFlow提供了默认的Buildermain-executor-class: com.yomahub.liteflow.thread.LiteFlowDefaultMainExecutorBuilder#自定义请求ID的生成类LiteFlow提供了默认的生成类request-id-generator-class: com.yomahub.liteflow.flow.id.DefaultRequestIdGenerator#并行节点的线程池BuilderLiteFlow提供了默认的Builderthread-executor-class: com.yomahub.liteflow.thread.LiteFlowDefaultWhenExecutorBuilder#异步线程最长的等待时间(只用于when)默认值为15000when-max-wait-time: 15000#异步线程最长的等待时间(只用于when)默认值为MILLISECONDS毫秒when-max-wait-time-unit: MILLISECONDS#when节点全局异步线程池最大线程数默认为16when-max-workers: 16#并行循环子项线程池最大线程数默认为16parallelLoop-max-workers: 16#并行循环子项线程池等待队列数默认为512parallelLoop-queue-limit: 512#并行循环子项的线程池BuilderLiteFlow提供了默认的BuilderparallelLoop-executor-class: com.yomahub.liteflow.thread.LiteFlowDefaultParallelLoopExecutorBuilder#when节点全局异步线程池等待队列数默认为512when-queue-limit: 512#是否在启动的时候就解析规则默认为trueparse-on-start: true#全局重试次数默认为0retry-count: 0#是否支持不同类型的加载方式混用默认为falsesupport-multiple-type: false#全局默认节点执行器node-executor-class: com.yomahub.liteflow.flow.executor.DefaultNodeExecutor#是否打印执行中过程中的日志默认为trueprint-execution-log: true#是否开启本地文件监听默认为falseenable-monitor-file: false#是否开启快速解析模式默认为falsefast-load: false#简易监控配置选项monitor:#监控是否开启默认不开启enable-log: false#监控队列存储大小默认值为200queue-limit: 200#监控一开始延迟多少执行默认值为300000毫秒也就是5分钟delay: 300000#监控日志打印每过多少时间执行一次默认值为300000毫秒也就是5分钟period: 300000
3、SpringBoot中执行LiteFlow
声明启动类确保定义的组件扫入Spring上下文
SpringBootApplication
//把你定义的组件扫入Spring上下文中
ComponentScan({com.xxx.xxx.cmp})
public class LiteflowExampleApplication {public static void main(String[] args) {SpringApplication.run(LiteflowExampleApplication.class, args);}
}
然后可以在在Springboot任意被Spring托管的类中拿到flowExecutor进行执行链路
这里进行单元测试
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.flow.LiteflowResponse;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;RunWith(SpringRunner.class)
SpringBootTest(classes RuoYiApplication.class,webEnvironment SpringBootTest.WebEnvironment.RANDOM_PORT)
public class LiteFlowTest {Resourceprivate FlowExecutor flowExecutor;Testpublic void helloLiteFlow() {LiteflowResponse response flowExecutor.execute2Resp(chain1);System.out.println(response);}
}
这里的chain1与上面规则文件中的对应。
运行结果 可以看到三个组件依次执行这是因为配置的规则文件中配置的规则如此。
除了上面配置的普通组件之外还可配置其他组件比如选择组件、条件组件、循环组件等
普通组件 | LiteFlow 下面配置一个选择组件为例
在实际业务中往往要通过动态的业务逻辑判断到底接下去该执行哪一个节点这就引申出了选择节点
选择节点可以用于SWITCH关键字中。
关于SWITCH表达式的用法可以参考选择编排一章。
选择节点a需要继承NodeSwitchComponent。
需要实现方法processSwitch方法
import com.yomahub.liteflow.core.NodeSwitchComponent;
import org.springframework.stereotype.Component;Component(switchCmp)
public class SwitchCmp extends NodeSwitchComponent {Overridepublic String processSwitch() throws Exception {System.out.println(switchCmp executed!);//自己业务选择//以下代表选择了switchCmpA节点return switchCmpA;}
}
配置规则文件
?xml version1.0 encodingUTF-8?
flowchain namechain1THEN(acmp, bcmp, ccmp);/chainchain nameswitch_chainSWITCH(switchCmp).to(switchCmpA, switchCmpB);/chain
/flow
其中switchCmpA与switchCmpB是普通组件
编写单元测试 Testpublic void switchTest() {LiteflowResponse response flowExecutor.execute2Resp(switch_chain);}
运行结果 条件组件用法
LiteFlow从2.8.5版本开始提供了条件组件的定义。
条件组件也可以称之为IF组件返回是一个true/false。可用于IF...ELIF...ELSE等关键字。
关于IF...ELIF...ELSE表达式的用法可以参考条件编排这一章。
比如一个IF三元表达式如下所示xcmp就是IF组件为真执行acmp为假执行bcmp chain nameif_chainIF(xcmp, acmp, bcmp);/chain
编写条件组件
import com.yomahub.liteflow.core.NodeIfComponent;
import org.springframework.stereotype.Component;Component(xcmp)
public class XCmp extends NodeIfComponent {Overridepublic boolean processIf() throws Exception {//自己的业务判断return false;}
}
其它更多组件用法参考官方文档。
4、LiteFlow组件传参
在一个流程中总会有一些初始的参数比如订单号用户Id等等一些的初始参数。
这时候需要通过以下方法的第二个参数传入
public LiteflowResponse execute2Resp(String chainId, Object param, Class?... contextBeanClazzArray)
这个流程入参可以是任何对象一般生产业务场景下你可以把自己封装好的Bean传入。
编写传参组件
import com.ruoyi.system.domain.BusStudent;
import com.yomahub.liteflow.core.NodeIfComponent;
import org.springframework.stereotype.Component;Component(xpcmp)
public class XParamCmp extends NodeIfComponent {Overridepublic boolean processIf() throws Exception {//自己的业务判断BusStudent requestData this.getRequestData();if(null!requestData.getName()公众号:霸道的程序猿.equals(requestData.getName())){return true;}else{return false;}}
}
传参使用
flowExecutor.execute2Resp(if_param_chain, BusStudent.builder().name(公众号:霸道的程序猿).build());
5、LiteFlow声明式组件
普通组件和条件组件在写法上需要你自己去定义一个类去继承NodeComponent或者NodeSwitchComponent。
这样一方面造成了耦合另一方面由于java是单继承制所以使用者就无法再去继承自己的类了在自由度上就少了很多玩法。
声明式组件这一特性允许你自定义的组件不继承任何类和实现任何接口普通的类也可以依靠注解来完成LiteFlow组件的声明。
甚至于你可以用一个类去定义多个组件仅仅依靠注解就可以完成这个特性也叫做方法级别式声明
类级别式声明主要用处就是通过注解形式让普通的java bean变成LiteFlow的组件。无需通过继承类或者实现接口的方式。
由于LiteFlow的组件常规方式下需要继承类来定义使得你无法再继承自己业务的类了。这个特性可以解决这个问题。
但是和常规组件一样需要一个类对应一个组件
自定义一个组件并使用方法级别声明
import com.yomahub.liteflow.annotation.LiteflowCmpDefine;
import com.yomahub.liteflow.annotation.LiteflowComponent;
import com.yomahub.liteflow.annotation.LiteflowMethod;
import com.yomahub.liteflow.core.NodeComponent;
import com.yomahub.liteflow.enums.LiteFlowMethodEnum;LiteflowComponent(defineCmp)
LiteflowCmpDefine
public class DefineCmp{LiteflowMethod(LiteFlowMethodEnum.PROCESS)public void processAcmp(NodeComponent bindCmp) {System.out.println(ACmp executed!);}LiteflowMethod(LiteFlowMethodEnum.IS_ACCESS)public boolean isAcmpAccess(NodeComponent bindCmp){return true;}LiteflowMethod(LiteFlowMethodEnum.BEFORE_PROCESS)public void beforeAcmp(NodeComponent bindCmp){System.out.println(before A);}LiteflowMethod(LiteFlowMethodEnum.AFTER_PROCESS)public void afterAcmp(NodeComponent bindCmp){System.out.println(after A);}LiteflowMethod(LiteFlowMethodEnum.ON_SUCCESS)public void onAcmpSuccess(NodeComponent bindCmp){System.out.println(Acmp success);}LiteflowMethod(LiteFlowMethodEnum.ON_ERROR)public void onAcmpError(NodeComponent bindCmp, Exception e){System.out.println(Acmp error);}LiteflowMethod(LiteFlowMethodEnum.IS_END)public boolean isAcmpEnd(NodeComponent bindCmp) {return false;}LiteflowMethod(value LiteFlowMethodEnum.ROLLBACK)public void rollbackA(NodeComponent bindCmp) throws Exception {System.out.println(ACmp rollback!);}
}
同样实现效果。
6、LiteFlow还有更多功能和属性
比如EL规则的编排
说明 | LiteFlow
用代码动态构造规则
说明 | LiteFlow
以及各种给高级特性、平滑热更新等。
具体参考官方文档说明。
DEMO案例
滑动验证页面