🌰构造EL
# 依赖
从2.11.1版本开始,你可以在代码中动态组装EL表达式,包括创建、修改、输出EL表达式。
如果需要在代码中动态构建EL表达式,需要添加以下额外依赖:
<dependency>
<groupId>com.yomahub</groupId>
<artifactId>liteflow-el-builder</artifactId>
<version>2.13.1</version>
</dependency>
# 基本用法
你可以通过工厂类ELBus创建任何一个EL表达式。比如对于这样一个EL表达式:
图示
可以调用如下方法组装该表达式:
// 组装EL表达式
ThenELWrapper el = ELBus.then(
"a",
ELBus.when("b", ELBus.then("c", "d")),
"e");
System.out.println(el.toEL());
可以调用toEL()
方法输出EL表达式:
THEN(a,WHEN(b,THEN(c,d)),e)
# 在表达式上设置子关键字
你可以在相应的地方调用子关键字,比如id
,tag
,bind
,any
等等,下面是几个例子
String el = ELBus.switchOpt("x").to(ELBus.when("a,b").id("x1"), "c").toEL();
System.out.println(el);
//输出:SWITCH(x).TO(WHEN(a,b).id("x1"),c);
String el = ELBus.then(ELBus.when("a", "b").any(true), "c").bind("k1","v1").toEL();
System.out.println(el);
//输出:THEN(WHEN(a,b).any(true),c).bind("k1", "v1");
# 在节点上设置子关键字
以上都是在表达式层面设置关键字,可能会有人疑问,如果我要在节点上设置data
,tag
,bind
怎么办呢。
这里你需要用到ELBus.element("a")
或是ELBus.node("a")
。这两者的效果分别如下:
String el = ELBus.then(ELBus.element("a").tag("t1"), ELBus.element("b").bind("k1", "v1")).toEL();
System.out.println(el);
//输出:THEN(a.tag("t1"),b.bind("k1", "v1"));
String el = ELBus.then(ELBus.node("a").tag("t1"), ELBus.node("b").bind("k1", "v1")).toEL();
System.out.println(el);
//输出:THEN(node("a").tag("t1"),node("b").bind("k1", "v1"));
可以看到,其实ELBus.then("a")
和ELBus.then(ELBus.element("a")
是等价的,不同的是后者是可以设置子关键字的。
而ELBus.node("a")
则是给节点外面套上了node
关键字,其意义是在加载的时候不检查和降级,关于node
关键字的详细可参考组件名包装以及组件降级。
提示
其实用java去构造EL表达式的思路和书写表达式的思路是一样的。其结构几乎是完全一样的。这个相信开发者多加以试试就能举一反三。
这里只是针对几种情况做一些介绍,不会一一介绍每个方法。
# 格式化输出EL表达式
容易能发现toEL()
方法输出的EL表达式是一行字符串,不方便查看以及校验EL表达式是否正确。可以使用 toEL(true)
方法以树形结构输出EL表达式,以下是一个例子:
// EL表达式组装
WhenELWrapper el = ELBus.when("a",
ELBus.when(ELBus.node("b").data("whenData", "{\"name\":\"zhangsan\",\"age\":18}"))
.when("c")
.id("this is a id"),
"d").tag("this is a tag").any(true);
System.out.println(el.toEL(true));
输出得到:
whenData = '{"name":"zhangsan","age":18}';
WHEN(
node("a"),
WHEN(
node("b").data(whenData),
node("c")
).id("this is a id"),
node("d")
).any(true).tag("this is a tag")
# 目前支持的表达式和关键字
目前支持到2.13.0版本的所有EL表达式,包括其中的关键字和高级特性。当前支持的详细内容如下表:
EL表达式 | 创建方法 | 支持调用方法 | 支持关键字 |
---|---|---|---|
串行编排 | ELBus.then | then(Object ... objects) | pre finally tag id maxWaitSeconds data bind |
并行编排 | ELBus.when | when(Object ... objects) | any ignoreError customThreadExecutor must tag id maxWaitSeconds data bind |
选择编排 | ELBus.switch | to(Object... objects) defaultOpt(Object object) | tag id maxWaitSeconds data bind |
条件编排 | ELBus.ifOpt | elseOpt(Object falseObject) elIfOpt(Object ifObject, Object trueObject) | tag id maxWaitSeconds data bind |
循环编排 | ELBus.forOpt ELBus.whileOpt ELBus.iteratorOpt | doOpt(Object object) breakOpt(Object object) (ITERATOR迭代器循环表达式不支持) | parallel tag id maxWaitSeconds |
捕获异常表达式 | ELBus.catchException | doOpt(Object object) | tag id maxWaitSeconds |
与表达式 | ELBus.and | and(Object ... object) | tag id maxWaitSeconds data bind |
或表达式 | ELBus.or | or(Object ... object) | tag id maxWaitSeconds |
非表达式 | ELBus.not | tag id maxWaitSeconds data bind | |
单节点表达式 | ELBus.node | tag data maxWaitSeconds data bind | |
前置组件 | 通过then组件的pre关键字创建 | tag id maxWaitSeconds data bind | |
后置组件 | 通过then组件的finally关键字创建 | tag id data bind |
# EL表达式参数校验
组装表达式时会对表达式的参数类型进行校验。包括是否为单节点组件、是否允许为与或非表达式等。比如,WHILE表达式WHILE(w).DO(THEN(a, b));
中,w需要是返回布尔值的节点或与或非表达式。
更多测试样例请在 liteflow-testcase-el/liteflow-testcase-el-builder
模块中查看。