Просмотр исходного кода

enhancement #IA9NOI ELBus中增加对retry构建的api支持
enhancement #IA9QBG el-builder的部分重构

everywhere.z 10 месяцев назад
Родитель
Сommit
ff40b749b7
23 измененных файлов с 333 добавлено и 295 удалено
  1. 1 11
      liteflow-el-builder/src/main/java/com/yomahub/liteflow/builder/el/AndELWrapper.java
  2. 11 5
      liteflow-el-builder/src/main/java/com/yomahub/liteflow/builder/el/CatchELWrapper.java
  3. 46 46
      liteflow-el-builder/src/main/java/com/yomahub/liteflow/builder/el/ELBus.java
  4. 26 0
      liteflow-el-builder/src/main/java/com/yomahub/liteflow/builder/el/ELWrapper.java
  5. 11 4
      liteflow-el-builder/src/main/java/com/yomahub/liteflow/builder/el/FinallyELWrapper.java
  6. 0 63
      liteflow-el-builder/src/main/java/com/yomahub/liteflow/builder/el/ForELWrapper.java
  7. 13 5
      liteflow-el-builder/src/main/java/com/yomahub/liteflow/builder/el/IfELWrapper.java
  8. 0 51
      liteflow-el-builder/src/main/java/com/yomahub/liteflow/builder/el/IteratorELWrapper.java
  9. 31 6
      liteflow-el-builder/src/main/java/com/yomahub/liteflow/builder/el/LoopELWrapper.java
  10. 13 0
      liteflow-el-builder/src/main/java/com/yomahub/liteflow/builder/el/NodeELWrapper.java
  11. 0 6
      liteflow-el-builder/src/main/java/com/yomahub/liteflow/builder/el/NotELWrapper.java
  12. 1 11
      liteflow-el-builder/src/main/java/com/yomahub/liteflow/builder/el/OrELWrapper.java
  13. 11 1
      liteflow-el-builder/src/main/java/com/yomahub/liteflow/builder/el/ParELWrapper.java
  14. 10 0
      liteflow-el-builder/src/main/java/com/yomahub/liteflow/builder/el/PreELWrapper.java
  15. 11 1
      liteflow-el-builder/src/main/java/com/yomahub/liteflow/builder/el/SerELWrapper.java
  16. 12 5
      liteflow-el-builder/src/main/java/com/yomahub/liteflow/builder/el/SwitchELWrapper.java
  17. 11 3
      liteflow-el-builder/src/main/java/com/yomahub/liteflow/builder/el/ThenELWrapper.java
  18. 11 2
      liteflow-el-builder/src/main/java/com/yomahub/liteflow/builder/el/WhenELWrapper.java
  19. 0 58
      liteflow-el-builder/src/main/java/com/yomahub/liteflow/builder/el/WhileELWrapper.java
  20. 37 0
      liteflow-el-builder/src/main/java/com/yomahub/liteflow/builder/el/vo/RetryELVo.java
  21. 9 14
      liteflow-testcase-el/liteflow-testcase-el-builder/src/test/java/com/yomahub/liteflow/test/builder/LogicELBuilderTest.java
  22. 9 3
      liteflow-testcase-el/liteflow-testcase-el-builder/src/test/java/com/yomahub/liteflow/test/builder/MaxWaitSecondBuilderTest.java
  23. 59 0
      liteflow-testcase-el/liteflow-testcase-el-builder/src/test/java/com/yomahub/liteflow/test/builder/RetryBuilderTest.java

+ 1 - 11
liteflow-el-builder/src/main/java/com/yomahub/liteflow/builder/el/AndELWrapper.java

@@ -1,9 +1,5 @@
 package com.yomahub.liteflow.builder.el;
 
-import com.yomahub.liteflow.util.JsonUtil;
-
-import java.util.Map;
-
 /**
  * 与或非表达式中的 与表达式
  * 参数允许任意数量 参数必须返回true或false
@@ -21,7 +17,7 @@ public class AndELWrapper extends ELWrapper {
     }
 
     public AndELWrapper and(Object ... object){
-        ELWrapper[] wrapper = ELBus.convertToLogicOpt(object);
+        ELWrapper[] wrapper = ELBus.convertToBooleanOpt(object);
         this.addWrapper(wrapper);
         return this;
     }
@@ -38,12 +34,6 @@ public class AndELWrapper extends ELWrapper {
         return this;
     }
 
-    @Override
-    public AndELWrapper maxWaitSeconds(Integer maxWaitSeconds){
-        setMaxWaitSeconds(maxWaitSeconds);
-        return this;
-    }
-
     @Override
     protected String toEL(Integer depth, StringBuilder paramContext) {
         // 根据depth是否为null,决定输出是否格式化

+ 11 - 5
liteflow-el-builder/src/main/java/com/yomahub/liteflow/builder/el/CatchELWrapper.java

@@ -1,9 +1,5 @@
 package com.yomahub.liteflow.builder.el;
 
-import com.yomahub.liteflow.util.JsonUtil;
-
-import java.util.Map;
-
 /**
  * 捕获异常表达式
  * Catch(a).do(b)
@@ -22,7 +18,7 @@ public class CatchELWrapper extends ELWrapper {
     }
 
     public CatchELWrapper doOpt(Object object){
-        ELWrapper elWrapper = ELBus.convertToNonLogicOpt(object);
+        ELWrapper elWrapper = ELBus.convertToNonBooleanOpt(object);
         this.addWrapper(elWrapper);
         return this;
     }
@@ -45,6 +41,16 @@ public class CatchELWrapper extends ELWrapper {
         return this;
     }
 
+    public CatchELWrapper retry(Integer count){
+        super.retry(count);
+        return this;
+    }
+
+    public CatchELWrapper retry(Integer count, String... exceptions){
+        super.retry(count, exceptions);
+        return this;
+    }
+
     @Override
     protected String toEL(Integer depth, StringBuilder paramContext) {
         Integer sonDepth = depth == null ? null : depth + 1;

+ 46 - 46
liteflow-el-builder/src/main/java/com/yomahub/liteflow/builder/el/ELBus.java

@@ -27,7 +27,7 @@ public class ELBus {
     }
 
     public static ThenELWrapper then(Object ... objects){
-        ELWrapper[] elWrappers = convertToNonLogicOpt(objects);
+        ELWrapper[] elWrappers = convertToNonBooleanOpt(objects);
         return new ThenELWrapper(elWrappers);
     }
 
@@ -43,7 +43,7 @@ public class ELBus {
     }
 
     public static WhenELWrapper when(Object ... objects){
-        ELWrapper[] elWrappers = convertToNonLogicOpt(objects);
+        ELWrapper[] elWrappers = convertToNonBooleanOpt(objects);
         return new WhenELWrapper(elWrappers);
     }
 
@@ -53,7 +53,7 @@ public class ELBus {
     }
 
     public static SerELWrapper ser(Object ... objects){
-        ELWrapper[] elWrappers = convertToNonLogicOpt(objects);
+        ELWrapper[] elWrappers = convertToNonBooleanOpt(objects);
         return new SerELWrapper(elWrappers);
     }
 
@@ -69,7 +69,7 @@ public class ELBus {
     }
 
     public static ParELWrapper par(Object ... objects){
-        ELWrapper[] elWrappers = convertToNonLogicOpt(objects);
+        ELWrapper[] elWrappers = convertToNonBooleanOpt(objects);
         return new ParELWrapper(elWrappers);
     }
 
@@ -83,43 +83,43 @@ public class ELBus {
      * @return {@link IfELWrapper}
      */
     public static IfELWrapper ifOpt(NodeELWrapper ifElWrapper, Object trueElWrapper, Object falseElWrapper){
-        return new IfELWrapper(ifElWrapper, convertToNonLogicOpt(trueElWrapper), convertToNonLogicOpt(falseElWrapper));
+        return new IfELWrapper(ifElWrapper, convertToNonBooleanOpt(trueElWrapper), convertToNonBooleanOpt(falseElWrapper));
     }
 
     public static IfELWrapper ifOpt(String ifElWrapper, Object trueElWrapper, Object falseElWrapper){
-        return new IfELWrapper((NodeELWrapper) convertToLogicOpt(ifElWrapper), convertToNonLogicOpt(trueElWrapper), convertToNonLogicOpt(falseElWrapper));
+        return new IfELWrapper((NodeELWrapper) convertToBooleanOpt(ifElWrapper), convertToNonBooleanOpt(trueElWrapper), convertToNonBooleanOpt(falseElWrapper));
     }
 
     public static IfELWrapper ifOpt(AndELWrapper ifElWrapper, Object trueElWrapper, Object falseElWrapper){
-        return new IfELWrapper(ifElWrapper, convertToNonLogicOpt(trueElWrapper), convertToNonLogicOpt(falseElWrapper));
+        return new IfELWrapper(ifElWrapper, convertToNonBooleanOpt(trueElWrapper), convertToNonBooleanOpt(falseElWrapper));
     }
 
     public static IfELWrapper ifOpt(OrELWrapper ifElWrapper, Object trueElWrapper, Object falseElWrapper){
-        return new IfELWrapper(ifElWrapper, convertToNonLogicOpt(trueElWrapper), convertToNonLogicOpt(falseElWrapper));
+        return new IfELWrapper(ifElWrapper, convertToNonBooleanOpt(trueElWrapper), convertToNonBooleanOpt(falseElWrapper));
     }
 
     public static IfELWrapper ifOpt(NotELWrapper ifElWrapper, Object trueElWrapper, Object falseElWrapper){
-        return new IfELWrapper(ifElWrapper, convertToNonLogicOpt(trueElWrapper), convertToNonLogicOpt(falseElWrapper));
+        return new IfELWrapper(ifElWrapper, convertToNonBooleanOpt(trueElWrapper), convertToNonBooleanOpt(falseElWrapper));
     }
 
     public static IfELWrapper ifOpt(NodeELWrapper ifElWrapper, Object trueElWrapper){
-        return new IfELWrapper(ifElWrapper, convertToNonLogicOpt(trueElWrapper));
+        return new IfELWrapper(ifElWrapper, convertToNonBooleanOpt(trueElWrapper));
     }
 
     public static IfELWrapper ifOpt(String ifElWrapper, Object trueElWrapper){
-        return new IfELWrapper((NodeELWrapper) convertToLogicOpt(ifElWrapper), convertToNonLogicOpt(trueElWrapper));
+        return new IfELWrapper((NodeELWrapper) convertToBooleanOpt(ifElWrapper), convertToNonBooleanOpt(trueElWrapper));
     }
 
     public static IfELWrapper ifOpt(AndELWrapper ifElWrapper, Object trueElWrapper){
-        return new IfELWrapper(ifElWrapper, convertToNonLogicOpt(trueElWrapper));
+        return new IfELWrapper(ifElWrapper, convertToNonBooleanOpt(trueElWrapper));
     }
 
     public static IfELWrapper ifOpt(OrELWrapper ifElWrapper, Object trueElWrapper){
-        return new IfELWrapper(ifElWrapper, convertToNonLogicOpt(trueElWrapper));
+        return new IfELWrapper(ifElWrapper, convertToNonBooleanOpt(trueElWrapper));
     }
 
     public static IfELWrapper ifOpt(NotELWrapper ifElWrapper, Object trueElWrapper){
-        return new IfELWrapper(ifElWrapper, convertToNonLogicOpt(trueElWrapper));
+        return new IfELWrapper(ifElWrapper, convertToNonBooleanOpt(trueElWrapper));
     }
 
     /**
@@ -150,70 +150,70 @@ public class ELBus {
      * 创建 for 次数循环表达式
      *
      * @param loopNumber 循环次数
-     * @return {@link ForELWrapper}
+     * @return {@link LoopELWrapper}
      */
-    public static ForELWrapper forOpt(Integer loopNumber){
-        return new ForELWrapper(loopNumber, "FOR");
+    public static LoopELWrapper forOpt(Integer loopNumber){
+        return new LoopELWrapper(loopNumber, LoopELWrapper.FOR);
     }
 
     /**
      * 创建 for 次数循环表达式
      *
      * @param nodeElWrapper 返回循环次数的节点
-     * @return {@link ForELWrapper}
+     * @return {@link LoopELWrapper}
      */
-    public static ForELWrapper forOpt(NodeELWrapper nodeElWrapper){
-        return new ForELWrapper(nodeElWrapper, "FOR");
+    public static LoopELWrapper forOpt(NodeELWrapper nodeElWrapper){
+        return new LoopELWrapper(nodeElWrapper, LoopELWrapper.FOR);
     }
 
     /**
      * 创建 for 次数循环表达式
      *
      * @param nodeElWrapper 返回循环次数的节点Id
-     * @return {@link ForELWrapper}
+     * @return {@link LoopELWrapper}
      */
-    public static ForELWrapper forOpt(String nodeElWrapper){
-        return new ForELWrapper(convert(nodeElWrapper), "FOR");
+    public static LoopELWrapper forOpt(String nodeElWrapper){
+        return new LoopELWrapper(convert(nodeElWrapper), LoopELWrapper.FOR);
     }
 
     /**
      * 创建 while 条件循环表达式
      *
      * @param nodeElWrapper 返回布尔值的节点
-     * @return {@link WhileELWrapper}
+     * @return {@link LoopELWrapper}
      */
-    public static WhileELWrapper whileOpt(NodeELWrapper nodeElWrapper){
-        return new WhileELWrapper(nodeElWrapper, "WHILE");
+    public static LoopELWrapper whileOpt(NodeELWrapper nodeElWrapper){
+        return new LoopELWrapper(nodeElWrapper, LoopELWrapper.WHILE);
     }
 
-    public static WhileELWrapper whileOpt(String nodeElWrapper){
-        return new WhileELWrapper(convert(nodeElWrapper), "WHILE");
+    public static LoopELWrapper whileOpt(String nodeElWrapper){
+        return new LoopELWrapper(convert(nodeElWrapper), LoopELWrapper.WHILE);
     }
 
-    public static WhileELWrapper whileOpt(AndELWrapper andElWrapper){
-        return new WhileELWrapper(andElWrapper, "WHILE");
+    public static LoopELWrapper whileOpt(AndELWrapper andElWrapper){
+        return new LoopELWrapper(andElWrapper, LoopELWrapper.WHILE);
     }
 
-    public static WhileELWrapper whileOpt(OrELWrapper orElWrapper){
-        return new WhileELWrapper(orElWrapper, "WHILE");
+    public static LoopELWrapper whileOpt(OrELWrapper orElWrapper){
+        return new LoopELWrapper(orElWrapper, LoopELWrapper.WHILE);
     }
 
-    public static WhileELWrapper whileOpt(NotELWrapper notElWrapper){
-        return new WhileELWrapper(notElWrapper, "WHILE");
+    public static LoopELWrapper whileOpt(NotELWrapper notElWrapper){
+        return new LoopELWrapper(notElWrapper, LoopELWrapper.WHILE);
     }
 
     /**
      * 创建迭代循环表达式
      *
      * @param nodeElWrapper 迭代节点
-     * @return {@link IteratorELWrapper}
+     * @return {@link LoopELWrapper}
      */
-    public static IteratorELWrapper iteratorOpt(NodeELWrapper nodeElWrapper){
-        return new IteratorELWrapper(nodeElWrapper, "ITERATOR");
+    public static LoopELWrapper iteratorOpt(NodeELWrapper nodeElWrapper){
+        return new LoopELWrapper(nodeElWrapper, LoopELWrapper.ITERATOR);
     }
 
-    public static IteratorELWrapper iteratorOpt(String nodeElWrapper){
-        return new IteratorELWrapper(convert(nodeElWrapper), "ITERATOR");
+    public static LoopELWrapper iteratorOpt(String nodeElWrapper){
+        return new LoopELWrapper(convert(nodeElWrapper), LoopELWrapper.ITERATOR);
     }
 
     /**
@@ -223,7 +223,7 @@ public class ELBus {
      * @return {@link CatchELWrapper}
      */
     public static CatchELWrapper catchException(Object object){
-        return new CatchELWrapper(convertToNonLogicOpt(object));
+        return new CatchELWrapper(convertToNonBooleanOpt(object));
     }
 
     /**
@@ -233,7 +233,7 @@ public class ELBus {
      * @return {@link AndELWrapper}
      */
     public static AndELWrapper and(Object ... objects){
-        ELWrapper[] elWrappers = convertToLogicOpt(objects);
+        ELWrapper[] elWrappers = convertToBooleanOpt(objects);
         return new AndELWrapper(elWrappers);
     }
 
@@ -244,7 +244,7 @@ public class ELBus {
      * @return {@link OrELWrapper}
      */
     public static OrELWrapper or(Object ... objects){
-        ELWrapper[] elWrappers = convertToLogicOpt(objects);
+        ELWrapper[] elWrappers = convertToBooleanOpt(objects);
         return new OrELWrapper(elWrappers);
     }
 
@@ -309,13 +309,13 @@ public class ELBus {
      * @param objects 表达式或字符串
      * @return {@link ELWrapper[]}
      */
-    public static ELWrapper[] convertToLogicOpt(Object... objects){
+    public static ELWrapper[] convertToBooleanOpt(Object... objects){
         ELWrapper[] elWrappers = convert(objects);
         checkBooleanArgs(elWrappers);
         return elWrappers;
     }
 
-    public static ELWrapper convertToLogicOpt(Object object){
+    public static ELWrapper convertToBooleanOpt(Object object){
         ELWrapper elWrapper = convert(object);
         checkBooleanArgs(elWrapper);
         return elWrapper;
@@ -327,13 +327,13 @@ public class ELBus {
      * @param objects 表达式或字符串
      * @return {@link ELWrapper[]}
      */
-    public static ELWrapper[] convertToNonLogicOpt(Object ... objects){
+    public static ELWrapper[] convertToNonBooleanOpt(Object ... objects){
         ELWrapper[] elWrappers = convert(objects);
         checkNotBooleanArgs(elWrappers);
         return elWrappers;
     }
 
-    public static ELWrapper convertToNonLogicOpt(Object object){
+    public static ELWrapper convertToNonBooleanOpt(Object object){
         ELWrapper elWrapper = convert(object);
         checkNotBooleanArgs(elWrapper);
         return elWrapper;

+ 26 - 0
liteflow-el-builder/src/main/java/com/yomahub/liteflow/builder/el/ELWrapper.java

@@ -1,6 +1,7 @@
 package com.yomahub.liteflow.builder.el;
 
 import cn.hutool.core.util.StrUtil;
+import com.yomahub.liteflow.builder.el.vo.RetryELVo;
 import com.yomahub.liteflow.util.JsonUtil;
 
 import java.util.ArrayList;
@@ -13,6 +14,7 @@ import java.util.Map;
  * 定义所有EL表达式的公有变量 tag、id、data、maxWaitSeconds 以及 子表达式列表 ELWrapperList
  *
  * @author gezuao
+ * @author Bryan.Zhang
  * @since 2.11.1
  */
 public abstract class ELWrapper {
@@ -24,6 +26,7 @@ public abstract class ELWrapper {
     private String dataName;
     private String data;
     private Integer maxWaitSeconds;
+    private RetryELVo retry;
 
     protected void addWrapper(ELWrapper wrapper){
         this.elWrapperList.add(wrapper);
@@ -89,6 +92,14 @@ public abstract class ELWrapper {
         return this.maxWaitSeconds;
     }
 
+    protected RetryELVo getRetry() {
+        return retry;
+    }
+
+    protected void setRetry(RetryELVo retry) {
+        this.retry = retry;
+    }
+
     /**
      * 设置组件标记内容
      *
@@ -156,6 +167,18 @@ public abstract class ELWrapper {
         return this;
     }
 
+    protected ELWrapper retry(int count){
+        RetryELVo item = new RetryELVo(count);
+        setRetry(item);
+        return this;
+    }
+
+    protected ELWrapper retry(int count, String... exceptions){
+        RetryELVo item = new RetryELVo(count, exceptions);
+        setRetry(item);
+        return this;
+    }
+
     /**
      * 非格式化输出EL表达式
      *
@@ -207,6 +230,9 @@ public abstract class ELWrapper {
         if(this.getMaxWaitSeconds() != null){
             elContext.append(StrUtil.format(".maxWaitSeconds({})", String.valueOf(this.getMaxWaitSeconds())));
         }
+        if (this.getRetry() != null){
+            elContext.append(StrUtil.format(".retry({})", this.getRetry().toString()));
+        }
     }
 
     /**

+ 11 - 4
liteflow-el-builder/src/main/java/com/yomahub/liteflow/builder/el/FinallyELWrapper.java

@@ -1,9 +1,6 @@
 package com.yomahub.liteflow.builder.el;
 
 import cn.hutool.core.util.StrUtil;
-import com.yomahub.liteflow.util.JsonUtil;
-
-import java.util.Map;
 
 /**
  * 后置表达式
@@ -16,7 +13,7 @@ import java.util.Map;
  */
 public class FinallyELWrapper extends ELWrapper {
     public FinallyELWrapper(Object ... objects){
-        super.addWrapper(ELBus.convertToNonLogicOpt(objects));
+        super.addWrapper(ELBus.convertToNonBooleanOpt(objects));
     }
 
     @Override
@@ -43,6 +40,16 @@ public class FinallyELWrapper extends ELWrapper {
         return this;
     }
 
+    public FinallyELWrapper retry(Integer count){
+        super.retry(count);
+        return this;
+    }
+
+    public FinallyELWrapper retry(Integer count, String... exceptions){
+        super.retry(count, exceptions);
+        return this;
+    }
+
     @Override
     protected String toEL(Integer depth, StringBuilder paramContext) {
         Integer sonDepth = depth == null ? null : depth + 1;

+ 0 - 63
liteflow-el-builder/src/main/java/com/yomahub/liteflow/builder/el/ForELWrapper.java

@@ -1,63 +0,0 @@
-package com.yomahub.liteflow.builder.el;
-
-import com.yomahub.liteflow.util.JsonUtil;
-
-import java.util.Map;
-
-/**
- * 次数循环表达式
- * FOR只允许一个参数 参数为 Integer 或 返回循环次数的 EL表达式
- * DO只允许一个参数 参数类型不为与或非表达式
- * 支持调用break方法,参数为与或非表达式或返回true false的单节点
- *
- * 支持设置 id tag data maxWaitSeconds 以及 parallel 属性
- *
- * @author gezuao
- * @since 2.11.1
- */
-public class ForELWrapper extends LoopELWrapper {
-
-    public ForELWrapper(Integer loopNumber, String loopFunction){
-        super(loopNumber, loopFunction);
-    }
-
-    public ForELWrapper(ELWrapper elWrapper, String loopFunction){
-        super(elWrapper, loopFunction);
-    }
-
-    @Override
-    public ForELWrapper doOpt(Object object){
-        ELWrapper elWrapper = ELBus.convertToNonLogicOpt(object);
-        super.addWrapper(elWrapper, 1);
-        return this;
-    }
-
-    public ForELWrapper breakOpt(Object object){
-        ELWrapper elWrapper = ELBus.convertToLogicOpt(object);
-        super.addWrapper(elWrapper, 2);
-        return this;
-    }
-
-    public ForELWrapper parallel(boolean parallel){
-        setParallel(parallel);
-        return this;
-    }
-
-    @Override
-    public ForELWrapper tag(String tag) {
-        this.setTag(tag);
-        return this;
-    }
-
-    @Override
-    public ForELWrapper id(String id) {
-        this.setId(id);
-        return this;
-    }
-
-    @Override
-    public ForELWrapper maxWaitSeconds(Integer maxWaitSeconds){
-        setMaxWaitSeconds(maxWaitSeconds);
-        return this;
-    }
-}

+ 13 - 5
liteflow-el-builder/src/main/java/com/yomahub/liteflow/builder/el/IfELWrapper.java

@@ -1,9 +1,7 @@
 package com.yomahub.liteflow.builder.el;
 
 import cn.hutool.core.util.ObjectUtil;
-import com.yomahub.liteflow.util.JsonUtil;
 
-import java.util.Map;
 import java.util.Objects;
 
 /**
@@ -115,7 +113,7 @@ public class IfELWrapper extends ELWrapper {
      * @return {@link IfELWrapper}
      */
     public IfELWrapper elseOpt(Object falseObject){
-        ELWrapper falseWrapper = ELBus.convertToNonLogicOpt(falseObject);
+        ELWrapper falseWrapper = ELBus.convertToNonBooleanOpt(falseObject);
         // 找到最深层的if组件
         ELWrapper prev = this;
         ELWrapper succ = this;
@@ -138,8 +136,8 @@ public class IfELWrapper extends ELWrapper {
      */
     public IfELWrapper elIfOpt(Object ifObject, Object trueObject) {
         // 包装判断表达式和true分支组件
-        ELWrapper ifWrapper = ELBus.convertToLogicOpt(ifObject);
-        ELWrapper trueWrapper = ELBus.convertToNonLogicOpt(trueObject);
+        ELWrapper ifWrapper = ELBus.convertToBooleanOpt(ifObject);
+        ELWrapper trueWrapper = ELBus.convertToNonBooleanOpt(trueObject);
         IfELWrapper elIfWrapper;
         if(ifWrapper instanceof NodeELWrapper){
             elIfWrapper = new IfELWrapper((NodeELWrapper) ifWrapper, trueWrapper);
@@ -219,6 +217,16 @@ public class IfELWrapper extends ELWrapper {
         return this;
     }
 
+    public IfELWrapper retry(Integer count){
+        super.retry(count);
+        return this;
+    }
+
+    public IfELWrapper retry(Integer count, String... exceptions){
+        super.retry(count, exceptions);
+        return this;
+    }
+
     @Override
     protected String toEL(Integer depth, StringBuilder paramContext) {
         Integer sonDepth = depth == null ? null : depth + 1;

+ 0 - 51
liteflow-el-builder/src/main/java/com/yomahub/liteflow/builder/el/IteratorELWrapper.java

@@ -1,51 +0,0 @@
-package com.yomahub.liteflow.builder.el;
-
-import com.yomahub.liteflow.util.JsonUtil;
-
-import java.util.Map;
-
-/**
- * 迭代循环表达式
- * ITERATOR只允许一个参数 参数为 EL表达式
- * DO只允许一个参数 参数类型不为与或非表达式
- *
- * 支持设置 id tag data maxWaitSeconds 以及 parallel 属性
- *
- * @author gezuao
- * @since 2.11.1
- */
-public class IteratorELWrapper extends LoopELWrapper {
-    public IteratorELWrapper(ELWrapper elWrapper, String loopFunction){
-        super(elWrapper, loopFunction);
-    }
-
-    public IteratorELWrapper parallel(boolean parallel){
-        setParallel(parallel);
-        return this;
-    }
-
-    @Override
-    public IteratorELWrapper doOpt(Object object){
-        ELWrapper elWrapper = ELBus.convertToNonLogicOpt(object);
-        super.addWrapper(elWrapper, 1);
-        return this;
-    }
-
-    @Override
-    public IteratorELWrapper tag(String tag) {
-        this.setTag(tag);
-        return this;
-    }
-
-    @Override
-    public IteratorELWrapper id(String id) {
-        this.setId(id);
-        return this;
-    }
-
-    @Override
-    public IteratorELWrapper maxWaitSeconds(Integer maxWaitSeconds){
-        setMaxWaitSeconds(maxWaitSeconds);
-        return this;
-    }
-}

+ 31 - 6
liteflow-el-builder/src/main/java/com/yomahub/liteflow/builder/el/LoopELWrapper.java

@@ -1,16 +1,19 @@
 package com.yomahub.liteflow.builder.el;
 
-import com.yomahub.liteflow.util.JsonUtil;
-
-import java.util.Map;
-
 /**
  * FOR、WHILE、ITERATOR循环表达式的公共抽象父类
  *
  * @author gezuao
+ * @author Bryan.Zhang
  * @since 2.11.1
  */
-public abstract class LoopELWrapper extends ELWrapper {
+public class LoopELWrapper extends ELWrapper {
+
+    public final static String FOR = "FOR";
+
+    public final static String WHILE = "WHILE";
+
+    public final static String ITERATOR = "ITERATOR";
 
     protected Integer loopNumber;
 
@@ -32,12 +35,23 @@ public abstract class LoopELWrapper extends ELWrapper {
         this.addWrapper(elWrapper, 0);
     }
 
+    public LoopELWrapper parallel(boolean parallel){
+        setParallel(parallel);
+        return this;
+    }
+
     public LoopELWrapper doOpt(Object object){
-        ELWrapper elWrapper = ELBus.convertToNonLogicOpt(object);
+        ELWrapper elWrapper = ELBus.convertToNonBooleanOpt(object);
         this.addWrapper(elWrapper, 1);
         return this;
     }
 
+    public LoopELWrapper breakOpt(Object object){
+        ELWrapper elWrapper = ELBus.convertToBooleanOpt(object);
+        super.addWrapper(elWrapper, 2);
+        return this;
+    }
+
     protected void setParallel(boolean parallel){
         this.parallel = parallel;
     }
@@ -60,6 +74,17 @@ public abstract class LoopELWrapper extends ELWrapper {
         return this;
     }
 
+    public LoopELWrapper retry(Integer count){
+        super.retry(count);
+        return this;
+    }
+
+    public LoopELWrapper retry(Integer count, String... exceptions){
+        super.retry(count, exceptions);
+        return this;
+    }
+
+
     @Override
     protected String toEL(Integer depth, StringBuilder paramContext) {
         Integer sonDepth = depth == null ? null : depth + 1;

+ 13 - 0
liteflow-el-builder/src/main/java/com/yomahub/liteflow/builder/el/NodeELWrapper.java

@@ -85,6 +85,16 @@ public class NodeELWrapper extends ELWrapper {
         return this;
     }
 
+    public NodeELWrapper retry(Integer count){
+        super.retry(count);
+        return this;
+    }
+
+    public NodeELWrapper retry(Integer count, String... exceptions){
+        super.retry(count, exceptions);
+        return this;
+    }
+
     @Override
     protected String toEL(Integer depth, StringBuilder paramContext) {
         NodeELWrapper nodeElWrapper = this.getNodeWrapper();
@@ -117,5 +127,8 @@ public class NodeELWrapper extends ELWrapper {
         if(this.getMaxWaitSeconds() != null){
             elContext.append(StrUtil.format(".maxWaitSeconds({})", String.valueOf(this.getMaxWaitSeconds())));
         }
+        if (this.getRetry() != null){
+            elContext.append(StrUtil.format(".retry({})", this.getRetry().toString()));
+        }
     }
 }

+ 0 - 6
liteflow-el-builder/src/main/java/com/yomahub/liteflow/builder/el/NotELWrapper.java

@@ -30,12 +30,6 @@ public class NotELWrapper extends ELWrapper {
         return this;
     }
 
-    @Override
-    public NotELWrapper maxWaitSeconds(Integer maxWaitSeconds){
-        setMaxWaitSeconds(maxWaitSeconds);
-        return this;
-    }
-
     @Override
     protected String toEL(Integer depth, StringBuilder paramContext) {
         Integer sonDepth = depth == null ? null : depth + 1;

+ 1 - 11
liteflow-el-builder/src/main/java/com/yomahub/liteflow/builder/el/OrELWrapper.java

@@ -1,9 +1,5 @@
 package com.yomahub.liteflow.builder.el;
 
-import com.yomahub.liteflow.util.JsonUtil;
-
-import java.util.Map;
-
 /**
  * 与或非表达式中的 或表达式
  * 参数允许任意数量 参数必须返回true或false
@@ -21,7 +17,7 @@ public class OrELWrapper extends ELWrapper {
     }
 
     public OrELWrapper or(Object ... object){
-        ELWrapper[] elWrapper = ELBus.convertToLogicOpt(object);
+        ELWrapper[] elWrapper = ELBus.convertToBooleanOpt(object);
         this.addWrapper(elWrapper);
         return this;
     }
@@ -38,12 +34,6 @@ public class OrELWrapper extends ELWrapper {
         return this;
     }
 
-    @Override
-    public OrELWrapper maxWaitSeconds(Integer maxWaitSeconds){
-        setMaxWaitSeconds(maxWaitSeconds);
-        return this;
-    }
-
     @Override
     protected String toEL(Integer depth, StringBuilder paramContext) {
         Integer sonDepth = depth == null ? null : depth + 1;

+ 11 - 1
liteflow-el-builder/src/main/java/com/yomahub/liteflow/builder/el/ParELWrapper.java

@@ -32,7 +32,7 @@ public class ParELWrapper extends ELWrapper {
     }
 
     public ParELWrapper par(Object ... objects){
-        ELWrapper[] elWrappers = ELBus.convertToNonLogicOpt(objects);
+        ELWrapper[] elWrappers = ELBus.convertToNonBooleanOpt(objects);
         // 校验与或非表达式
         this.addWrapper(elWrappers);
         return this;
@@ -76,6 +76,16 @@ public class ParELWrapper extends ELWrapper {
         return this;
     }
 
+    public ParELWrapper retry(Integer count){
+        super.retry(count);
+        return this;
+    }
+
+    public ParELWrapper retry(Integer count, String... exceptions){
+        super.retry(count, exceptions);
+        return this;
+    }
+
     @Override
     protected String toEL(Integer depth, StringBuilder paramContext) {
         Integer sonDepth = depth == null ? null : depth + 1;

+ 10 - 0
liteflow-el-builder/src/main/java/com/yomahub/liteflow/builder/el/PreELWrapper.java

@@ -36,6 +36,16 @@ public class PreELWrapper extends ELWrapper {
         return this;
     }
 
+    public PreELWrapper retry(Integer count){
+        super.retry(count);
+        return this;
+    }
+
+    public PreELWrapper retry(Integer count, String... exceptions){
+        super.retry(count, exceptions);
+        return this;
+    }
+
     @Override
     protected String toEL(Integer depth, StringBuilder paramContext) {
         Integer sonDepth = depth == null ? null : depth + 1;

+ 11 - 1
liteflow-el-builder/src/main/java/com/yomahub/liteflow/builder/el/SerELWrapper.java

@@ -26,7 +26,7 @@ public class SerELWrapper extends ELWrapper {
     }
 
     public SerELWrapper ser(Object ... objects){
-        ELWrapper[] elWrappers = ELBus.convertToNonLogicOpt(objects);
+        ELWrapper[] elWrappers = ELBus.convertToNonBooleanOpt(objects);
         // 校验与或非表达式
         this.addWrapper(elWrappers);
         return this;
@@ -80,6 +80,16 @@ public class SerELWrapper extends ELWrapper {
         return this;
     }
 
+    public SerELWrapper retry(Integer count){
+        super.retry(count);
+        return this;
+    }
+
+    public SerELWrapper retry(Integer count, String... exceptions){
+        super.retry(count, exceptions);
+        return this;
+    }
+
     @Override
     protected String toEL(Integer depth, StringBuilder paramContext) {
         Integer sonDepth = depth == null ? null : depth + 1;

+ 12 - 5
liteflow-el-builder/src/main/java/com/yomahub/liteflow/builder/el/SwitchELWrapper.java

@@ -1,9 +1,6 @@
 package com.yomahub.liteflow.builder.el;
 
 import cn.hutool.core.util.StrUtil;
-import com.yomahub.liteflow.util.JsonUtil;
-
-import java.util.Map;
 
 /**
  * 选择组件
@@ -28,13 +25,13 @@ public class SwitchELWrapper extends ELWrapper {
     }
 
     public SwitchELWrapper to(Object... objects){
-        ELWrapper[] elWrappers = ELBus.convertToNonLogicOpt(objects);
+        ELWrapper[] elWrappers = ELBus.convertToNonBooleanOpt(objects);
         this.addWrapper(elWrappers);
         return this;
     }
 
     public SwitchELWrapper defaultOpt(Object object){
-        defaultElWrapper = ELBus.convertToNonLogicOpt(object);
+        defaultElWrapper = ELBus.convertToNonBooleanOpt(object);
         return this;
     }
 
@@ -56,6 +53,16 @@ public class SwitchELWrapper extends ELWrapper {
         return this;
     }
 
+    public SwitchELWrapper retry(Integer count){
+        super.retry(count);
+        return this;
+    }
+
+    public SwitchELWrapper retry(Integer count, String... exceptions){
+        super.retry(count, exceptions);
+        return this;
+    }
+
     @Override
     protected String toEL(Integer depth, StringBuilder paramContext) {
         Integer sonDepth = depth == null ? null : depth + 1;

+ 11 - 3
liteflow-el-builder/src/main/java/com/yomahub/liteflow/builder/el/ThenELWrapper.java

@@ -1,11 +1,9 @@
 package com.yomahub.liteflow.builder.el;
 
 import cn.hutool.core.util.StrUtil;
-import com.yomahub.liteflow.util.JsonUtil;
 
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Map;
 
 /**
  * 串行组件
@@ -28,7 +26,7 @@ public class ThenELWrapper extends ELWrapper {
     }
 
     public ThenELWrapper then(Object ... objects){
-        ELWrapper[] elWrappers = ELBus.convertToNonLogicOpt(objects);
+        ELWrapper[] elWrappers = ELBus.convertToNonBooleanOpt(objects);
         // 校验与或非表达式
         this.addWrapper(elWrappers);
         return this;
@@ -82,6 +80,16 @@ public class ThenELWrapper extends ELWrapper {
         return this;
     }
 
+    public ThenELWrapper retry(Integer count){
+        super.retry(count);
+        return this;
+    }
+
+    public ThenELWrapper retry(Integer count, String... exceptions){
+        super.retry(count, exceptions);
+        return this;
+    }
+
     @Override
     protected String toEL(Integer depth, StringBuilder paramContext) {
         Integer sonDepth = depth == null ? null : depth + 1;

+ 11 - 2
liteflow-el-builder/src/main/java/com/yomahub/liteflow/builder/el/WhenELWrapper.java

@@ -2,7 +2,6 @@ package com.yomahub.liteflow.builder.el;
 
 import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.core.util.StrUtil;
-import com.yomahub.liteflow.util.JsonUtil;
 
 import java.util.*;
 
@@ -31,7 +30,7 @@ public class WhenELWrapper extends ELWrapper {
     }
 
     public WhenELWrapper when(Object ... objects){
-        ELWrapper[] elWrappers = ELBus.convertToNonLogicOpt(objects);
+        ELWrapper[] elWrappers = ELBus.convertToNonBooleanOpt(objects);
         // 校验与或非表达式
         this.addWrapper(elWrappers);
         return this;
@@ -75,6 +74,16 @@ public class WhenELWrapper extends ELWrapper {
         return this;
     }
 
+    public WhenELWrapper retry(Integer count){
+        super.retry(count);
+        return this;
+    }
+
+    public WhenELWrapper retry(Integer count, String... exceptions){
+        super.retry(count, exceptions);
+        return this;
+    }
+
     @Override
     protected String toEL(Integer depth, StringBuilder paramContext) {
         Integer sonDepth = depth == null ? null : depth + 1;

+ 0 - 58
liteflow-el-builder/src/main/java/com/yomahub/liteflow/builder/el/WhileELWrapper.java

@@ -1,58 +0,0 @@
-package com.yomahub.liteflow.builder.el;
-
-import com.yomahub.liteflow.util.JsonUtil;
-
-import java.util.Map;
-
-/**
- * 条件循环表达式
- * WHILE只允许一个参数 参数为 返回布尔值的EL表达式
- * DO只允许一个参数 参数类型不为与或非表达式
- * 支持调用break方法,参数为与或非表达式或返回true false的单节点
- *
- * 支持设置 id tag data maxWaitSeconds 以及 parallel 属性
- *
- * @author gezuao
- * @since 2.11.1
- */
-public class WhileELWrapper extends LoopELWrapper {
-    public WhileELWrapper(ELWrapper elWrapper, String loopFunction){
-        super(elWrapper, loopFunction);
-    }
-
-    public WhileELWrapper parallel(boolean parallel){
-        setParallel(parallel);
-        return this;
-    }
-
-    @Override
-    public WhileELWrapper doOpt(Object object){
-        ELWrapper elWrapper = ELBus.convertToNonLogicOpt(object);
-        super.addWrapper(elWrapper, 1);
-        return this;
-    }
-
-    public WhileELWrapper breakOpt(Object object){
-        ELWrapper elWrapper = ELBus.convertToLogicOpt(object);
-        super.addWrapper(elWrapper, 2);
-        return this;
-    }
-
-    @Override
-    public WhileELWrapper tag(String tag) {
-        this.setTag(tag);
-        return this;
-    }
-
-    @Override
-    public WhileELWrapper id(String id) {
-        this.setId(id);
-        return this;
-    }
-
-    @Override
-    public WhileELWrapper maxWaitSeconds(Integer maxWaitSeconds){
-        setMaxWaitSeconds(maxWaitSeconds);
-        return this;
-    }
-}

+ 37 - 0
liteflow-el-builder/src/main/java/com/yomahub/liteflow/builder/el/vo/RetryELVo.java

@@ -0,0 +1,37 @@
+package com.yomahub.liteflow.builder.el.vo;
+
+import cn.hutool.core.util.StrUtil;
+
+import java.util.Arrays;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+ * 用于ELBus中设置retry关键字的对象
+ * @author Bryan.Zhang
+ * @since 2.12.2
+ */
+public class RetryELVo {
+
+    private int count;
+
+    private String[] exceptions;
+
+    public RetryELVo(int count) {
+        this.count = count;
+    }
+
+    public RetryELVo(int count, String... exceptions) {
+        this.count = count;
+        this.exceptions = exceptions;
+    }
+
+    @Override
+    public String toString() {
+        if (exceptions == null) {
+            return StrUtil.format("{}", count);
+        }else{
+            return StrUtil.format("{},{}", count, Arrays.stream(exceptions).map(s -> StrUtil.format("\"{}\"", s)).collect(Collectors.joining(",")));
+        }
+    }
+}

+ 9 - 14
liteflow-testcase-el/liteflow-testcase-el-builder/src/test/java/com/yomahub/liteflow/test/builder/LogicELBuilderTest.java

@@ -57,19 +57,19 @@ public class LogicELBuilderTest extends BaseTest {
     // 属性设置
     @Test
     public void testlogic5(){
-        String expectedStr = "AND(node(\"a\"),OR(node(\"b\"),node(\"c\")).id(\"this is a id\"),NOT(node(\"d\")).tag(\"this is a tag\")).maxWaitSeconds(4);";
+        String expectedStr = "AND(node(\"a\"),OR(node(\"b\"),node(\"c\")).id(\"this is a id\"),NOT(node(\"d\")).tag(\"this is a tag\"));";
         Assertions.assertEquals(expectedStr,
-                ELBus.and("a", ELBus.or("b", "c").id("this is a id"), ELBus.not("d").tag("this is a tag")).maxWaitSeconds(4).toEL());
+                ELBus.and("a", ELBus.or("b", "c").id("this is a id"), ELBus.not("d").tag("this is a tag")).toEL());
         System.out.println(expectedStr);
-        Assertions.assertTrue(LiteFlowChainELBuilder.validate(ELBus.and("a", ELBus.or("b", "c").id("this is a id"), ELBus.not("d").tag("this is a tag")).maxWaitSeconds(4).toEL()));
+        Assertions.assertTrue(LiteFlowChainELBuilder.validate(ELBus.and("a", ELBus.or("b", "c").id("this is a id"), ELBus.not("d").tag("this is a tag")).toEL()));
     }
     @Test
     public void testlogic6(){
-        String expectedStr = "AND(\n\tnode(\"a\"),\n\tOR(\n\t\tnode(\"b\"),\n\t\tnode(\"c\")\n\t).id(\"this is a id\"),\n\tNOT(\n\t\tnode(\"d\")\n\t).tag(\"this is a tag\")\n).maxWaitSeconds(4);";
+        String expectedStr = "AND(\n\tnode(\"a\"),\n\tOR(\n\t\tnode(\"b\"),\n\t\tnode(\"c\")\n\t).id(\"this is a id\"),\n\tNOT(\n\t\tnode(\"d\")\n\t).tag(\"this is a tag\")\n);";
         Assertions.assertEquals(expectedStr,
-                ELBus.and("a", ELBus.or("b", "c").id("this is a id"), ELBus.not("d").tag("this is a tag")).maxWaitSeconds(4).toEL(true));
+                ELBus.and("a", ELBus.or("b", "c").id("this is a id"), ELBus.not("d").tag("this is a tag")).toEL(true));
         System.out.println(expectedStr);
-        Assertions.assertTrue(LiteFlowChainELBuilder.validate(ELBus.and("a", ELBus.or("b", "c").id("this is a id"), ELBus.not("d").tag("this is a tag")).maxWaitSeconds(4).toEL(true)));
+        Assertions.assertTrue(LiteFlowChainELBuilder.validate(ELBus.and("a", ELBus.or("b", "c").id("this is a id"), ELBus.not("d").tag("this is a tag")).toEL(true)));
     }
     @Test
     public void testlogic7(){
@@ -191,16 +191,11 @@ public class LogicELBuilderTest extends BaseTest {
 
     @Test
     public void testLogic(){
-        AndELWrapper andEl = ELBus.and("a", "b").id("this is a id").tag("this is a tag").maxWaitSeconds(5);
+        AndELWrapper andEl = ELBus.and("a", "b").id("this is a id").tag("this is a tag");
         Assertions.assertTrue(LiteFlowChainELBuilder.validate(andEl.toEL()));
-        OrELWrapper orEl = ELBus.or("a", "b").maxWaitSeconds(3);
+        OrELWrapper orEl = ELBus.or("a", "b");
         Assertions.assertTrue(LiteFlowChainELBuilder.validate(orEl.toEL()));
-        NotELWrapper notEl = ELBus.not("a").maxWaitSeconds(2);
+        NotELWrapper notEl = ELBus.not("a");
         Assertions.assertTrue(LiteFlowChainELBuilder.validate(notEl.toEL()));
-
-//        Assertions.assertTrue(LiteFlowChainELBuilder.validate("AND(node(\"a\"),OR(node(\"b\"),node(\"c\")).id(\"this is a id\"),NOT(node(\"d\")).tag(\"this is a tag\").maxWaitSeconds(3))"));
-
-//        ThenELWrapper thenELWrapper = ELBus.then(ELBus.when("a", "b", ELBus.when("c", "d").maxWaitSeconds(3)));
-//        Assertions.assertTrue(LiteFlowChainELBuilder.validate(thenELWrapper.toEL()));
     }
 }

+ 9 - 3
liteflow-testcase-el/liteflow-testcase-el-builder/src/test/java/com/yomahub/liteflow/test/builder/MaxWaitSecondBuilderTest.java

@@ -2,6 +2,7 @@ package com.yomahub.liteflow.test.builder;
 
 import com.yomahub.liteflow.builder.el.*;
 import com.yomahub.liteflow.test.BaseTest;
+import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
@@ -62,11 +63,16 @@ public class MaxWaitSecondBuilderTest extends BaseTest {
     // 循环层面
     @Test
     public void testMaxWaitSecond6(){
-        ForELWrapper forELWrapper = ELBus.forOpt(3).doOpt("a").maxWaitSeconds(5);
+        LoopELWrapper forELWrapper = ELBus.forOpt(3).doOpt("a").maxWaitSeconds(5);
         Assertions.assertEquals("FOR(3).DO(a).maxWaitSeconds(5);", forELWrapper.toEL());
-        WhileELWrapper whileELWrapper = ELBus.whileOpt("w").doOpt("a").maxWaitSeconds(5);
+        LoopELWrapper whileELWrapper = ELBus.whileOpt("w").doOpt("a").maxWaitSeconds(5);
         Assertions.assertEquals("WHILE(w).DO(a).maxWaitSeconds(5);", whileELWrapper.toEL());
-        IteratorELWrapper iteratorELWrapper = ELBus.iteratorOpt("i").doOpt("a").maxWaitSeconds(5);
+        LoopELWrapper iteratorELWrapper = ELBus.iteratorOpt("i").doOpt("a").maxWaitSeconds(5);
         Assertions.assertEquals("ITERATOR(i).DO(a).maxWaitSeconds(5);", iteratorELWrapper.toEL());
     }
+
+    @AfterAll
+    public static void after(){
+        ELBus.setNodeWrapper(true);
+    }
 }

+ 59 - 0
liteflow-testcase-el/liteflow-testcase-el-builder/src/test/java/com/yomahub/liteflow/test/builder/RetryBuilderTest.java

@@ -0,0 +1,59 @@
+package com.yomahub.liteflow.test.builder;
+
+import com.yomahub.liteflow.builder.el.*;
+import com.yomahub.liteflow.test.BaseTest;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.test.context.SpringBootTest;
+
+@SpringBootTest(classes = RetryBuilderTest.class)
+@EnableAutoConfiguration
+public class RetryBuilderTest extends BaseTest {
+
+    @BeforeAll
+    public static void init(){
+        ELBus.setNodeWrapper(false);
+    }
+
+    // node上进行retry
+    @Test
+    public void testRetry1(){
+        NodeELWrapper nodeA = ELBus.node("a").retry(2);
+        NodeELWrapper nodeB = ELBus.node("b").retry(3);
+        WhenELWrapper whenELWrapper = ELBus.when(nodeA, nodeB);
+        Assertions.assertEquals("WHEN(a.retry(2),b.retry(3));", whenELWrapper.toEL());
+    }
+
+    // node上进行retry,带exception
+    @Test
+    public void testRetry2(){
+        NodeELWrapper nodeA = ELBus.node("a").retry(2, "java.lang.NullPointerException");
+        NodeELWrapper nodeB = ELBus.node("b").retry(3, "java.lang.NullPointerException", "java.lang.ArrayIndexOutOfBoundsException");
+        WhenELWrapper whenELWrapper = ELBus.when(nodeA, nodeB);
+        Assertions.assertEquals("WHEN(a.retry(2,\"java.lang.NullPointerException\"),b.retry(3,\"java.lang.NullPointerException\",\"java.lang.ArrayIndexOutOfBoundsException\"));",
+                whenELWrapper.toEL());
+    }
+
+    // 在表达式上进行retry
+    @Test
+    public void testRetry3(){
+        WhenELWrapper whenELWrapper = ELBus.when("a", "b").retry(4);
+        Assertions.assertEquals("WHEN(a,b).retry(4);", whenELWrapper.toEL());
+    }
+
+    // 在表达式上进行retry, 带exception
+    @Test
+    public void testRetry4(){
+        WhenELWrapper whenELWrapper = ELBus.when("a", "b").retry(3, "java.lang.NullPointerException", "java.lang.ArrayIndexOutOfBoundsException");
+        Assertions.assertEquals("WHEN(a,b).retry(3,\"java.lang.NullPointerException\",\"java.lang.ArrayIndexOutOfBoundsException\");",
+                whenELWrapper.toEL());
+    }
+
+    @AfterAll
+    public static void after(){
+        ELBus.setNodeWrapper(true);
+    }
+}