liteflow学习二

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: liteflow学习二

前面我们看到了执行的具体逻辑,但是在哪里构建EL表达式的、获取的、执行的呢?

一、EL表达式的设置

在LiteFlowChainELBuilder可以看到EL表达式的逻辑基于阿里开源的QLExpress实现的, 在初始化QLExpress的Runner中,作者扩展了很多操作Operator。在setEL(String elStr)这个方法中,我们可以会将FlowBus中的chainMap和NodeMap放入到Context中,也即DefaultContext,同时放入当前的chainId。接着会解析el表达式,解析成最外部一个condition, 内部可以嵌套很多层。

可以看到构建EL表达式的过程中会涉及到chainMap和NodeMap放入到DefaultContext中:

DefaultContext<String, Object> context = new DefaultContext<>();
// 这里一定要先放chain,再放node,因为node优先于chain,所以当重名时,node会覆盖掉chain
FlowBus.getChainMap().values().forEach(chain -> context.put(chain.getChainId(), chain));
// 往上下文里放入所有的node,使得el表达式可以直接引用到nodeId
FlowBus.getNodeMap().keySet().forEach(nodeId -> context.put(nodeId, FlowBus.getNode(nodeId)));
// 放入当前主chain的ID
context.put(ChainConstant.CURR_CHAIN_ID, this.chain.getChainId());
// 解析el成为一个Condition
// 为什么这里只是一个Condition,而不是一个List<Condition>呢
// 这里无论多复杂的,外面必定有一个最外层的Condition,所以这里只有一个,内部可以嵌套很多层,这点和以前的不太一样
Condition condition = (Condition) EXPRESS_RUNNER.execute(elStr, context, errorList, true, true);
// 把主要的condition加入
this.conditionList.add(condition);

可以看到我们的WHEN表达式会进行WHEN的EL表达式的解析,此时经过BaseOperator会对对应的Operator进行依次构建。所有的Operator都会经过com.yomahub.liteflow.builder.el.operator.base.BaseOperator#executeInner进行build。

因此我们来看看WhenOperator是如何构建的。

public WhenCondition build(Object[] objects) throws Exception {
        OperatorHelper.checkObjectSizeGtZero(objects);
        WhenCondition whenCondition = new WhenCondition();
        for (Object obj : objects) {
            whenCondition.addExecutable(OperatorHelper.convert(obj, Executable.class));
        }
        return whenCondition;
    }

此时会将可执行的执行器放入到executableGroup中,方便执行condition的时候获取执行。

public void addExecutable(String groupKey, Executable executable) {
        System.out.println("添加执行的operator");
        if (ObjectUtil.isNull(executable)) {
            return;
        }
        List<Executable> executableList = this.executableGroup.get(groupKey);
        if (CollUtil.isEmpty(executableList)) {
            this.executableGroup.put(groupKey, ListUtil.toList(executable));
        }
        else {
            this.executableGroup.get(groupKey).add(executable);
        }
    }

前面我们已经知道,liteflow的执行逻辑是先获取chain,然后执行chain,然后执行condition,最终执行业务逻辑中的nodeComponent。因此我们来看看并行器是如何实现的。

二、并行器是如何实现

前面说到THEN打头的是串行器,而WHEN打头的是并行器,因此我们可以看到Condition中的并行器对应的WhenCondition。

可以看到执行的execution是executeAsyncCondition(slotIndex)。

前面看到初始化LiteflowConfig的时候,没有配置信息。可以看到线程池的配置信息就是配置在LiteflowConfig中的。并行编排的实现借助了封装CompletableFuture对象。

前面我们知道执行condition的方法是executeCondition(Integer slotIndex)。执行condition的核心方法是com.yomahub.liteflow.flow.element.condition.WhenCondition#executeAsyncCondition。

那么此时我们似乎在Future的代码中找不到调用的逻辑,如果看过我上一篇文章的话,那应该知道调用condition之后,会调用具体的node执行业务逻辑编排代码。因此此时我们可以根据之前的线索知道会调用node中的execute方法。因此我们可以查询引用的地方,从而找到对应的地方。

根据前的ThenCondition的调用,我们知道调用的过程condition到node的过程,因此这个过程必然会涉及到node的调用过程。因此我们可以知道对应的node的执行是在ParallelSupplier中。

public WhenFutureObj get() {
        try {
            executableItem.setCurrChainId(currChainId);
            executableItem.execute(slotIndex);
            return WhenFutureObj.success(executableItem.getId());
        }
        catch (Exception e) {
            return WhenFutureObj.fail(executableItem.getId(), e);
        }
    }

从而调用node执行具体的业务逻辑方法com.yomahub.liteflow.flow.element.Node#execute。

从而进一步调用我们自己写的业务逻辑。

总结下来即:组装数据chain、node ,构建EL表达式,然后根据通过槽拿到chain,从而进一步拿到condition,从而拿到node,调用业务系统继承NodeComponent重写的process方法。


三、UML图

这里我们了解了并行编排的相关执行流程后,当然这些都是基于正常情况下实现的编排。如果是异常情况下,或者说重试失败的情况下,又做怎样的处理呢?下一篇,我们来学习,因为在业务处理中,我们会用到,同时这也是框架留给我们继承重写的方法。因此需要了解。


参考:https://gitee.com/dromara/LiteFlow  LiteFlow的官网地址:https://liteflow.cc/

目录
相关文章
|
9月前
|
缓存 安全 PHP
【PHP开发专栏】Symfony框架核心组件解析
【4月更文挑战第30天】本文介绍了Symfony框架,一个模块化且高性能的PHP框架,以其可扩展性和灵活性备受开发者青睐。文章分为三部分,首先概述了Symfony的历史、特点和版本。接着,详细解析了HttpFoundation(处理HTTP请求和响应)、Routing(映射HTTP请求到控制器)、DependencyInjection(管理依赖关系)、EventDispatcher(实现事件驱动编程)以及Security(处理安全和认证)等核心组件。
178 3
|
ARouter 索引
|
6月前
|
缓存 前端开发 JavaScript
为什么用Vite框架?来看它的核心组件案例详解
Vite 是一款前沿的前端构建工具,以其闪电般的开发服务器和高效的生产构建而著称。它利用现代浏览器对 ES 模块的支持,在开发环境中提供快速启动及按需加载,显著提升了开发体验。Vite 的核心组件包括开发服务器、按需编译、依赖预构建、热模块替换(HMR)、缓存机制、模块路径重写、构建优化和插件系统。通过这些功能,Vite 实现了快速的模块加载、高效的模块更新、减少网络请求、以及生产环境下的代码压缩和优化。Vite 还支持多种前端框架和技术栈,内置 TypeScript 支持,并能处理 CSS 和静态资源,极大地方便了开发者的日常开发工作。
251 9
|
7月前
|
设计模式 测试技术 Python
《手把手教你》系列基础篇(九十二)-java+ selenium自动化测试-框架设计基础-POM设计模式简介(详解教程)
【7月更文挑战第10天】Page Object Model (POM)是Selenium自动化测试中的设计模式,用于提高代码的可读性和维护性。POM将每个页面表示为一个类,封装元素定位和交互操作,使得测试脚本与页面元素分离。当页面元素改变时,只需更新对应页面类,减少了脚本的重复工作和维护复杂度,有利于团队协作。POM通过创建页面对象,管理页面元素集合,将业务逻辑与元素定位解耦合,增强了代码的复用性。示例展示了不使用POM时,脚本直接混杂了元素定位和业务逻辑,而POM则能解决这一问题。
95 6
|
7月前
|
设计模式 Java 测试技术
《手把手教你》系列基础篇(九十四)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-下篇(详解教程)
【7月更文挑战第12天】在本文中,作者宏哥介绍了如何在不使用PageFactory的情况下,用Java和Selenium实现Page Object Model (POM)。文章通过一个百度首页登录的实战例子来说明。首先,创建了一个名为`BaiduHomePage1`的页面对象类,其中包含了页面元素的定位和相关操作方法。接着,创建了测试类`TestWithPOM1`,在测试类中初始化WebDriver,设置驱动路径,最大化窗口,并调用页面对象类的方法进行登录操作。这样,测试脚本保持简洁,遵循了POM模式的高可读性和可维护性原则。
86 2
|
7月前
|
设计模式 Java 测试技术
《手把手教你》系列基础篇(九十三)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-上篇(详解教程)
【7月更文挑战第11天】页面对象模型(POM)通过Page Factory在Java Selenium测试中被应用,简化了代码维护。在POM中,每个网页对应一个Page Class,其中包含页面元素和相关操作。对比之下,非POM实现直接在测试脚本中处理元素定位和交互,代码可读性和可维护性较低。
58 0
|
XML 测试技术 uml
liteflow学习一
liteflow学习一
643 0
|
9月前
liteflow快速开始
liteflow快速开始
117 0
|
9月前
|
XML Java API
Spring Boot 整合 LiteFlow 规则引擎:概念与实战
【4月更文挑战第30天】在现代软件开发中,规则引擎允许我们以声明式的方式定义业务逻辑和决策路径。LiteFlow 是一个轻量级、易于使用的组件式规则引擎,它可以与 Spring Boot 应用无缝整合。本文将介绍如何在 Spring Boot 项目中引入 LiteFlow,实现灵活的业务流程管理。
374 0
|
XML Java 数据格式
Spring源码系列:核心概念解析
Spring框架中有许多关键组件,理解这些组件的作用和关系可以帮助我们更好地阅读和理解Spring源码。BeanDefinition是Spring中重要的概念,定义了一个Bean的基本属性和行为,是Spring容器管理Bean的基础。我们可以通过注解或编程方式定义BeanDefinition,然后将其注册到Spring容器中。BeanDefinitionReader是读取和操作BeanDefinition的重要组件。其中XmlBeanDefinitionReader可以从XML文件中读取BeanDefinition,AnnotatedBeanDefinitionReader可以解析注解并注册B