enhancement #I5U5O6 对声明式类&方法进行了重构,提升了使用友好度

This commit is contained in:
everywhere.z
2022-10-04 23:36:06 +08:00
parent 0d99e2f64e
commit 0ef87467cd
10 changed files with 162 additions and 1 deletions

View File

@@ -0,0 +1,14 @@
package com.yomahub.liteflow.annotation;
import com.yomahub.liteflow.enums.NodeTypeEnum;
import java.lang.annotation.*;
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface LiteflowCmpDefine {
NodeTypeEnum value() default NodeTypeEnum.COMMON;
}

View File

@@ -1,12 +1,18 @@
package com.yomahub.liteflow.enums;
import cn.hutool.core.annotation.AnnotationUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.yomahub.liteflow.annotation.LiteflowCmpDefine;
import com.yomahub.liteflow.annotation.LiteflowMethod;
import com.yomahub.liteflow.core.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Predicate;
/**
* 节点类型枚举
@@ -38,6 +44,9 @@ public enum NodeTypeEnum {
BREAK_SCRIPT("break_script", "循环跳出脚本", true, ScriptBreakComponent.class)
;
private static final Logger LOG = LoggerFactory.getLogger(NodeTypeEnum.class);
private String code;
private String name;
@@ -116,6 +125,52 @@ public enum NodeTypeEnum {
public static NodeTypeEnum guessType(Class<?> clazz){
NodeTypeEnum nodeType = guessTypeBySuperClazz(clazz);
if (nodeType == null){
//尝试从类声明处进行推断
LiteflowCmpDefine liteflowCmpDefine = clazz.getAnnotation(LiteflowCmpDefine.class);
if (liteflowCmpDefine != null){
//类声明方式中@LiteflowMethod是无需设置nodeId的
//但是如果设置了那么核心逻辑其实是取类上定义的id的
//这种可以运行,但是理解起来不大好理解,所以给出提示,建议不要这么做
boolean mixDefined = Arrays.stream(clazz.getDeclaredMethods()).anyMatch(method -> {
LiteflowMethod liteflowMethod = AnnotationUtil.getAnnotation(method, LiteflowMethod.class);
if (liteflowMethod != null){
return StrUtil.isNotBlank(liteflowMethod.nodeId());
}else{
return false;
}
});
if (mixDefined){
LOG.warn("[[[WARNING!!!]]]The @liteflowMethod in the class[{}] defined by @liteflowCmpDefine should not configure the nodeId again!",
clazz.getName());
}
//在返回之前,还要对方法级别的@LiteflowMethod进行检查如果存在方法上的类型与类上的不一致时给予警告信息
AtomicReference<Method> differenceTypeMethod = new AtomicReference<>();
boolean hasDifferenceNodeType = Arrays.stream(clazz.getDeclaredMethods()).anyMatch(method -> {
LiteflowMethod liteflowMethod = AnnotationUtil.getAnnotation(method, LiteflowMethod.class);
if (liteflowMethod != null){
if (!liteflowMethod.nodeType().equals(liteflowCmpDefine.value())){
differenceTypeMethod.set(method);
return true;
}else{
return false;
}
}else{
return false;
}
});
//表示存在不一样的类型
if (hasDifferenceNodeType){
LOG.warn("[[[WARNING!!!]]]The nodeType in @liteflowCmpDefine declared on the class[{}] does not match the nodeType in @liteflowMethod declared on the method[{}]!",
clazz.getName(), differenceTypeMethod.get().getName());
}
return liteflowCmpDefine.value();
}
//再尝试声明式组件这部分的推断
LiteflowMethod liteflowMethod = Arrays.stream(clazz.getDeclaredMethods()).map(
method -> AnnotationUtil.getAnnotation(method, LiteflowMethod.class)

View File

@@ -0,0 +1,39 @@
package com.yomahub.liteflow.test.mixDefine;
import com.yomahub.liteflow.core.FlowExecutor;
import com.yomahub.liteflow.flow.LiteflowResponse;
import com.yomahub.liteflow.test.BaseTest;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
/**
* springboot环境最普通的例子测试
* @author Bryan.Zhang
* @since 2.6.4
*/
@RunWith(SpringRunner.class)
@TestPropertySource(value = "classpath:/mixDefine/application.properties")
@SpringBootTest(classes = MixDefineELDeclMultiSpringbootTest.class)
@EnableAutoConfiguration
@ComponentScan({"com.yomahub.liteflow.test.mixDefine.cmp"})
public class MixDefineELDeclMultiSpringbootTest extends BaseTest {
@Resource
private FlowExecutor flowExecutor;
//类声明和方法声明一起定义
@Test
public void testMixDefine1() throws Exception{
LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
Assert.assertTrue(response.isSuccess());
}
}

View File

@@ -0,0 +1,34 @@
package com.yomahub.liteflow.test.mixDefine.cmp;
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;
import com.yomahub.liteflow.enums.NodeTypeEnum;
import com.yomahub.liteflow.test.base.cmp.TestDomain;
import javax.annotation.Resource;
@LiteflowComponent("a")
@LiteflowCmpDefine(NodeTypeEnum.COMMON)
public class CmpConfig {
@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS)
public void processA(NodeComponent bindCmp) {
System.out.println("ACmp executed!");
}
@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS, nodeId = "c")
public void processC(NodeComponent bindCmp) {
System.out.println("CCmp executed!");
}
@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS_IF, nodeId = "d", nodeType = NodeTypeEnum.IF)
public boolean processIf(NodeComponent bindCmp) {
return true;
}
}

View File

@@ -0,0 +1 @@
liteflow.rule-source=mixDefine/flow.el.xml

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<flow>
<chain name="chain1">
THEN(a, c);
</chain>
</flow>

View File

@@ -7,12 +7,15 @@
*/
package com.yomahub.liteflow.test.base.cmp;
import com.yomahub.liteflow.annotation.LiteflowCmpDefine;
import com.yomahub.liteflow.annotation.LiteflowMethod;
import com.yomahub.liteflow.core.NodeComponent;
import com.yomahub.liteflow.enums.LiteFlowMethodEnum;
import com.yomahub.liteflow.enums.NodeTypeEnum;
import org.springframework.stereotype.Component;
@Component("a")
@LiteflowCmpDefine(NodeTypeEnum.COMMON)
public class ACmp{
@LiteflowMethod(LiteFlowMethodEnum.PROCESS)

View File

@@ -7,12 +7,15 @@
*/
package com.yomahub.liteflow.test.base.cmp;
import com.yomahub.liteflow.annotation.LiteflowCmpDefine;
import com.yomahub.liteflow.annotation.LiteflowMethod;
import com.yomahub.liteflow.core.NodeComponent;
import com.yomahub.liteflow.enums.LiteFlowMethodEnum;
import com.yomahub.liteflow.enums.NodeTypeEnum;
import org.springframework.stereotype.Component;
@Component("b")
@LiteflowCmpDefine(NodeTypeEnum.COMMON)
public class BCmp{
@LiteflowMethod(LiteFlowMethodEnum.PROCESS)

View File

@@ -7,12 +7,15 @@
*/
package com.yomahub.liteflow.test.base.cmp;
import com.yomahub.liteflow.annotation.LiteflowCmpDefine;
import com.yomahub.liteflow.annotation.LiteflowMethod;
import com.yomahub.liteflow.core.NodeComponent;
import com.yomahub.liteflow.enums.LiteFlowMethodEnum;
import com.yomahub.liteflow.enums.NodeTypeEnum;
import org.springframework.stereotype.Component;
@Component("c")
@LiteflowCmpDefine(NodeTypeEnum.COMMON)
public class CCmp{
@LiteflowMethod(LiteFlowMethodEnum.PROCESS)

View File

@@ -7,14 +7,17 @@
*/
package com.yomahub.liteflow.test.base.cmp;
import com.yomahub.liteflow.annotation.LiteflowCmpDefine;
import com.yomahub.liteflow.annotation.LiteflowMethod;
import com.yomahub.liteflow.core.NodeComponent;
import com.yomahub.liteflow.enums.LiteFlowMethodEnum;
import com.yomahub.liteflow.enums.NodeTypeEnum;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@Component("d")
@LiteflowCmpDefine(NodeTypeEnum.COMMON)
public class DCmp{
@Resource