feature #I9K14C 为process方法提供注入型参数特性
This commit is contained in:
parent
09aa29329d
commit
295bc0e2c6
|
@ -0,0 +1,12 @@
|
|||
package com.yomahub.liteflow.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.PARAMETER})
|
||||
@Documented
|
||||
@Inherited
|
||||
public @interface LiteflowFact {
|
||||
|
||||
String value();
|
||||
}
|
|
@ -1,17 +1,24 @@
|
|||
package com.yomahub.liteflow.core.proxy;
|
||||
|
||||
import cn.hutool.core.exceptions.InvocationTargetRuntimeException;
|
||||
import cn.hutool.core.lang.Tuple;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.ql.util.express.DefaultContext;
|
||||
import com.ql.util.express.ExpressRunner;
|
||||
import com.ql.util.express.InstructionSet;
|
||||
import com.yomahub.liteflow.annotation.LiteflowMethod;
|
||||
import com.yomahub.liteflow.annotation.LiteflowRetry;
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
import com.yomahub.liteflow.exception.ComponentMethodDefineErrorException;
|
||||
import com.yomahub.liteflow.exception.LiteFlowException;
|
||||
import com.yomahub.liteflow.exception.ParameterFactException;
|
||||
import com.yomahub.liteflow.exception.ProxyException;
|
||||
import com.yomahub.liteflow.flow.element.Node;
|
||||
import com.yomahub.liteflow.log.LFLog;
|
||||
import com.yomahub.liteflow.log.LFLoggerManager;
|
||||
import com.yomahub.liteflow.slot.DataBus;
|
||||
import com.yomahub.liteflow.util.SerialsUtil;
|
||||
import net.bytebuddy.ByteBuddy;
|
||||
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
|
||||
|
@ -21,7 +28,12 @@ import java.lang.annotation.Annotation;
|
|||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Parameter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
@ -112,6 +124,10 @@ public class DeclComponentProxy {
|
|||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
if (currentMethodWrapBean == null){
|
||||
throw new ProxyException("currentMethodWrapBean is null");
|
||||
}
|
||||
|
||||
// 如果被代理的对象里有此标注标的方法,则调用此被代理的对象里的方法,如果没有,则调用父类里的方法
|
||||
// 进行检查,检查被代理的bean里是否第一个参数为NodeComponent这个类型的
|
||||
boolean checkFlag = currentMethodWrapBean.getMethod().getParameterTypes().length > 0
|
||||
|
@ -124,13 +140,13 @@ public class DeclComponentProxy {
|
|||
throw new ComponentMethodDefineErrorException(errMsg);
|
||||
}
|
||||
|
||||
|
||||
// 这里是针对于参数的处理
|
||||
// 首先需要保证第一个参数是NodeComponent
|
||||
// 其次需要针对于@LiteflowFact做处理
|
||||
try {
|
||||
if (args != null && args.length > 0){
|
||||
Object[] wrapArgs = ArrayUtil.insert(args, 0, proxy);
|
||||
return ReflectUtil.invoke(declWarpBean.getRawBean(), currentMethodWrapBean.getMethod(), wrapArgs);
|
||||
}else{
|
||||
return ReflectUtil.invoke(declWarpBean.getRawBean(), currentMethodWrapBean.getMethod(), proxy);
|
||||
}
|
||||
Object[] realArgs = loadMethodParameter(proxy, currentMethodWrapBean);
|
||||
return ReflectUtil.invoke(declWarpBean.getRawBean(), currentMethodWrapBean.getMethod(), realArgs);
|
||||
}catch (InvocationTargetRuntimeException e) {
|
||||
InvocationTargetException targetEx = (InvocationTargetException) e.getCause();
|
||||
throw targetEx.getTargetException();
|
||||
|
@ -138,4 +154,55 @@ public class DeclComponentProxy {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
private final ExpressRunner expressRunner = new ExpressRunner();
|
||||
|
||||
private Object[] loadMethodParameter(Object proxy, MethodWrapBean methodWrapBean){
|
||||
NodeComponent thisNodeComponent = (NodeComponent) proxy;
|
||||
|
||||
return methodWrapBean.getParameterWrapBeanList().stream().map(parameterWrapBean -> {
|
||||
// 如果参数是NodeComponent,那就返回proxy本身
|
||||
if (parameterWrapBean.getParameterType().isAssignableFrom(NodeComponent.class)) {
|
||||
return proxy;
|
||||
}
|
||||
|
||||
// 如果没有@LiteflowFact标注,那么不处理,直接赋值null
|
||||
if (parameterWrapBean.getFact() == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 把上下文数据转换成map形式的,key为别名,value为上下文
|
||||
Map<String, Object> contextMap = DataBus.getSlot(thisNodeComponent.getSlotIndex()).getContextBeanList().stream().collect(
|
||||
Collectors.toMap(tuple -> tuple.get(0), tuple -> tuple.get(1))
|
||||
);
|
||||
|
||||
List<String> errorList = new ArrayList<>();
|
||||
|
||||
Object result = null;
|
||||
// 根据表达式去上下文里搜索相匹配的数据
|
||||
for(Map.Entry<String, Object> entry : contextMap.entrySet()){
|
||||
try{
|
||||
InstructionSet instructionSet = expressRunner.getInstructionSetFromLocalCache(entry.getKey() + "." + parameterWrapBean.getFact().value());
|
||||
DefaultContext<String, Object> context = new DefaultContext<>();
|
||||
context.put(entry.getKey(), entry.getValue());
|
||||
result = expressRunner.execute(instructionSet, context, errorList, false, false);
|
||||
if (result != null){
|
||||
break;
|
||||
}
|
||||
}catch (Exception ignore){}
|
||||
}
|
||||
|
||||
if (result == null){
|
||||
try{
|
||||
// 如果没有搜到,那么尝试推断表达式是指定的上下文,按照指定上下文的方式去再获取
|
||||
InstructionSet instructionSet = expressRunner.getInstructionSetFromLocalCache("contextMap." + parameterWrapBean.getFact().value());
|
||||
DefaultContext<String, Object> context = new DefaultContext<>();
|
||||
context.put("contextMap", contextMap);
|
||||
result = expressRunner.execute(instructionSet, context, errorList, false, false);
|
||||
}catch (Exception ignore){}
|
||||
}
|
||||
|
||||
return result;
|
||||
}).toArray();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import com.yomahub.liteflow.annotation.LiteflowMethod;
|
|||
import com.yomahub.liteflow.annotation.LiteflowRetry;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* LiteflowMethod的包装类
|
||||
|
@ -18,10 +19,13 @@ public class MethodWrapBean {
|
|||
|
||||
private LiteflowRetry liteflowRetry;
|
||||
|
||||
public MethodWrapBean(Method method, LiteflowMethod liteflowMethod, LiteflowRetry liteflowRetry) {
|
||||
private List<ParameterWrapBean> parameterWrapBeanList;
|
||||
|
||||
public MethodWrapBean(Method method, LiteflowMethod liteflowMethod, LiteflowRetry liteflowRetry, List<ParameterWrapBean> parameterWrapBeanList) {
|
||||
this.method = method;
|
||||
this.liteflowMethod = liteflowMethod;
|
||||
this.liteflowRetry = liteflowRetry;
|
||||
this.parameterWrapBeanList = parameterWrapBeanList;
|
||||
}
|
||||
|
||||
public Method getMethod() {
|
||||
|
@ -47,4 +51,12 @@ public class MethodWrapBean {
|
|||
public void setLiteflowRetry(LiteflowRetry liteflowRetry) {
|
||||
this.liteflowRetry = liteflowRetry;
|
||||
}
|
||||
|
||||
public List<ParameterWrapBean> getParameterWrapBeanList() {
|
||||
return parameterWrapBeanList;
|
||||
}
|
||||
|
||||
public void setParameterWrapBeanList(List<ParameterWrapBean> parameterWrapBeanList) {
|
||||
this.parameterWrapBeanList = parameterWrapBeanList;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
package com.yomahub.liteflow.core.proxy;
|
||||
|
||||
import com.yomahub.liteflow.annotation.LiteflowFact;
|
||||
|
||||
/**
|
||||
* 声明式的包装类
|
||||
* @author Bryan.Zhang
|
||||
* @since 2.12.1
|
||||
*/
|
||||
public class ParameterWrapBean {
|
||||
|
||||
private Class<?> parameterType;
|
||||
|
||||
private LiteflowFact fact;
|
||||
|
||||
private int index;
|
||||
|
||||
public ParameterWrapBean(Class<?> parameterType, LiteflowFact fact, int index) {
|
||||
this.parameterType = parameterType;
|
||||
this.fact = fact;
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public Class<?> getParameterType() {
|
||||
return parameterType;
|
||||
}
|
||||
|
||||
public void setParameterType(Class<?> parameterType) {
|
||||
this.parameterType = parameterType;
|
||||
}
|
||||
|
||||
public LiteflowFact getFact() {
|
||||
return fact;
|
||||
}
|
||||
|
||||
public void setFact(LiteflowFact fact) {
|
||||
this.fact = fact;
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
public void setIndex(int index) {
|
||||
this.index = index;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package com.yomahub.liteflow.exception;
|
||||
|
||||
/**
|
||||
* @author Bryan.Zhang
|
||||
*/
|
||||
public class ParameterFactException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 异常信息 */
|
||||
private String message;
|
||||
|
||||
public ParameterFactException(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,24 +1,27 @@
|
|||
package com.yomahub.liteflow.spi.spring;
|
||||
|
||||
import cn.hutool.core.annotation.AnnotationUtil;
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.yomahub.liteflow.annotation.LiteflowCmpDefine;
|
||||
import com.yomahub.liteflow.annotation.LiteflowComponent;
|
||||
import com.yomahub.liteflow.annotation.LiteflowMethod;
|
||||
import com.yomahub.liteflow.annotation.LiteflowRetry;
|
||||
import com.yomahub.liteflow.annotation.*;
|
||||
import com.yomahub.liteflow.annotation.util.AnnoUtil;
|
||||
import com.yomahub.liteflow.core.proxy.DeclWarpBean;
|
||||
import com.yomahub.liteflow.core.proxy.MethodWrapBean;
|
||||
import com.yomahub.liteflow.core.proxy.ParameterWrapBean;
|
||||
import com.yomahub.liteflow.enums.NodeTypeEnum;
|
||||
import com.yomahub.liteflow.exception.CmpDefinitionException;
|
||||
import com.yomahub.liteflow.spi.DeclComponentParser;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.lang.reflect.Parameter;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
/**
|
||||
* Spring环境声明式组件解析器实现
|
||||
|
@ -73,7 +76,16 @@ public class SpringDeclComponentParser implements DeclComponentParser {
|
|||
nodeType = liteflowMethod.nodeType();
|
||||
}
|
||||
|
||||
return new DeclInfo(currNodeId, currNodeName, nodeType, method.getDeclaringClass(), new MethodWrapBean(method, liteflowMethod, liteflowRetry));
|
||||
|
||||
Parameter[] parameters = method.getParameters();
|
||||
List<ParameterWrapBean> parameterList = IntStream.range(0, parameters.length).boxed().map(index -> {
|
||||
Parameter parameter = parameters[index];
|
||||
return new ParameterWrapBean(parameter.getType(), AnnotationUtil.getAnnotation(parameter, LiteflowFact.class), index);
|
||||
}).collect(Collectors.toList());
|
||||
|
||||
|
||||
|
||||
return new DeclInfo(currNodeId, currNodeName, nodeType, method.getDeclaringClass(), new MethodWrapBean(method, liteflowMethod, liteflowRetry, parameterList));
|
||||
}).filter(declInfo -> StrUtil.isNotBlank(declInfo.getNodeId())).collect(Collectors.groupingBy(DeclInfo::getNodeId));
|
||||
|
||||
return definitionMap.entrySet().stream().map(entry -> {
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
package com.yomahub.liteflow.test.processFact;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.yomahub.liteflow.core.FlowExecutor;
|
||||
import com.yomahub.liteflow.flow.LiteflowResponse;
|
||||
import com.yomahub.liteflow.test.BaseTest;
|
||||
import com.yomahub.liteflow.test.processFact.context.*;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
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.junit.jupiter.SpringExtension;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* process方法上的fact映射参数测试
|
||||
* @author Bryan.Zhang
|
||||
*/
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@TestPropertySource(value = "classpath:/processFact/application.properties")
|
||||
@SpringBootTest(classes = ProcessFactELDeclMultiSpringbootTest.class)
|
||||
@EnableAutoConfiguration
|
||||
@ComponentScan({"com.yomahub.liteflow.test.processFact.cmp"})
|
||||
public class ProcessFactELDeclMultiSpringbootTest extends BaseTest {
|
||||
|
||||
@Resource
|
||||
private FlowExecutor flowExecutor;
|
||||
|
||||
// 最基本的情况
|
||||
@Test
|
||||
public void testFact1() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg", createContext());
|
||||
Assertions.assertTrue(response.isSuccess());
|
||||
TestContext context = response.getContextBean(TestContext.class);
|
||||
Assertions.assertEquals("jack", context.getUser().getName());
|
||||
}
|
||||
|
||||
// 多上下文自动搜寻
|
||||
@Test
|
||||
public void testFact2() throws Exception {
|
||||
TestContext testContext = createContext();
|
||||
Demo1Context demo1Context = new Demo1Context();
|
||||
demo1Context.setData1("xxxx");
|
||||
demo1Context.setData2(99);
|
||||
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain2", "arg", demo1Context, testContext);
|
||||
Assertions.assertTrue(response.isSuccess());
|
||||
TestContext context = response.getContextBean(TestContext.class);
|
||||
Assertions.assertEquals(20, context.getUser().getCompany().getHeadCount());
|
||||
}
|
||||
|
||||
// 多上下文都有user,指定上下文中的user
|
||||
@Test
|
||||
public void testFact3() throws Exception {
|
||||
TestContext testContext = createContext();
|
||||
Demo2Context demo2Context = createDemo2Context();
|
||||
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain3", "arg", testContext, demo2Context);
|
||||
Assertions.assertTrue(response.isSuccess());
|
||||
Demo2Context context = response.getContextBean(Demo2Context.class);
|
||||
Assertions.assertEquals("rose", context.getUser().getName());
|
||||
}
|
||||
|
||||
// 多上下文都有user,指定上下文中的user
|
||||
@Test
|
||||
public void testFact4() throws Exception {
|
||||
Demo3Context demo3Context = createDemo3Context();
|
||||
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain4", "arg", demo3Context);
|
||||
Assertions.assertTrue(response.isSuccess());
|
||||
Demo3Context context = response.getContextBean(Demo3Context.class);
|
||||
Assertions.assertEquals("jelly", context.getUser().getName());
|
||||
}
|
||||
|
||||
private TestContext createContext(){
|
||||
Company company = new Company("XXX有限公司", "黄河路34号303室", 400);
|
||||
User user = new User("张三", 18, DateUtil.parseDate("1990-08-20"), company);
|
||||
return new TestContext(user, "this is data");
|
||||
}
|
||||
|
||||
private Demo2Context createDemo2Context(){
|
||||
Company company = new Company("XXX有限公司", "和平路12号101室", 600);
|
||||
User user = new User("李四", 28, DateUtil.parseDate("1990-06-01"), company);
|
||||
return new Demo2Context("xxx", user);
|
||||
}
|
||||
|
||||
private Demo3Context createDemo3Context(){
|
||||
Company company = new Company("XXX有限公司", "和平路12号101室", 600);
|
||||
User user = new User("王五", 28, DateUtil.parseDate("1990-06-01"), company);
|
||||
return new Demo3Context("xxx", user);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package com.yomahub.liteflow.test.processFact.cmp;
|
||||
|
||||
import cn.hutool.core.collection.ConcurrentHashSet;
|
||||
import com.yomahub.liteflow.annotation.LiteflowComponent;
|
||||
import com.yomahub.liteflow.annotation.LiteflowFact;
|
||||
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.slot.DefaultContext;
|
||||
import com.yomahub.liteflow.test.processFact.context.Company;
|
||||
import com.yomahub.liteflow.test.processFact.context.User;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@LiteflowComponent
|
||||
public class CmpConfig {
|
||||
|
||||
@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS, nodeType = NodeTypeEnum.COMMON, nodeId = "a")
|
||||
public void processA(NodeComponent bindCmp,
|
||||
@LiteflowFact("user") User user,
|
||||
@LiteflowFact("user.company.address") String address) {
|
||||
user.setName("jack");
|
||||
}
|
||||
|
||||
@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS, nodeType = NodeTypeEnum.COMMON, nodeId = "b")
|
||||
public void processB(NodeComponent bindCmp,
|
||||
@LiteflowFact("user.company") Company company,
|
||||
@LiteflowFact("data2") Integer data) {
|
||||
company.setHeadCount(20);
|
||||
}
|
||||
|
||||
@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS, nodeType = NodeTypeEnum.COMMON, nodeId = "c")
|
||||
public void processC(NodeComponent bindCmp,
|
||||
@LiteflowFact("demo2Context.user") User user) {
|
||||
user.setName("rose");
|
||||
}
|
||||
|
||||
@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS, nodeType = NodeTypeEnum.COMMON, nodeId = "d")
|
||||
public void processD(NodeComponent bindCmp,
|
||||
@LiteflowFact("ctx.user") User user) {
|
||||
user.setName("jelly");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package com.yomahub.liteflow.test.processFact.context;
|
||||
|
||||
public class Company {
|
||||
|
||||
private String name;
|
||||
|
||||
private String address;
|
||||
|
||||
private int headCount;
|
||||
|
||||
public Company(String name, String address, int headCount) {
|
||||
this.name = name;
|
||||
this.address = address;
|
||||
this.headCount = headCount;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(String address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public int getHeadCount() {
|
||||
return headCount;
|
||||
}
|
||||
|
||||
public void setHeadCount(int headCount) {
|
||||
this.headCount = headCount;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package com.yomahub.liteflow.test.processFact.context;
|
||||
|
||||
public class Demo1Context {
|
||||
|
||||
private String data1;
|
||||
|
||||
private Integer data2;
|
||||
|
||||
public String getData1() {
|
||||
return data1;
|
||||
}
|
||||
|
||||
public void setData1(String data1) {
|
||||
this.data1 = data1;
|
||||
}
|
||||
|
||||
public Integer getData2() {
|
||||
return data2;
|
||||
}
|
||||
|
||||
public void setData2(Integer data2) {
|
||||
this.data2 = data2;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package com.yomahub.liteflow.test.processFact.context;
|
||||
|
||||
public class Demo2Context {
|
||||
|
||||
private String data1;
|
||||
|
||||
private User user;
|
||||
|
||||
public Demo2Context(String data1, User user) {
|
||||
this.data1 = data1;
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public String getData1() {
|
||||
return data1;
|
||||
}
|
||||
|
||||
public void setData1(String data1) {
|
||||
this.data1 = data1;
|
||||
}
|
||||
|
||||
public User getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public void setUser(User user) {
|
||||
this.user = user;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package com.yomahub.liteflow.test.processFact.context;
|
||||
|
||||
import com.yomahub.liteflow.context.ContextBean;
|
||||
|
||||
@ContextBean("ctx")
|
||||
public class Demo3Context {
|
||||
|
||||
private String data1;
|
||||
|
||||
private User user;
|
||||
|
||||
public Demo3Context(String data1, User user) {
|
||||
this.data1 = data1;
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public String getData1() {
|
||||
return data1;
|
||||
}
|
||||
|
||||
public void setData1(String data1) {
|
||||
this.data1 = data1;
|
||||
}
|
||||
|
||||
public User getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public void setUser(User user) {
|
||||
this.user = user;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package com.yomahub.liteflow.test.processFact.context;
|
||||
|
||||
public class TestContext {
|
||||
|
||||
private User user;
|
||||
|
||||
private String data1;
|
||||
|
||||
public TestContext(User user, String data1) {
|
||||
this.user = user;
|
||||
this.data1 = data1;
|
||||
}
|
||||
|
||||
public User getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public void setUser(User user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public String getData1() {
|
||||
return data1;
|
||||
}
|
||||
|
||||
public void setData1(String data1) {
|
||||
this.data1 = data1;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package com.yomahub.liteflow.test.processFact.context;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public class User {
|
||||
|
||||
private String name;
|
||||
|
||||
private int age;
|
||||
|
||||
private Date birthday;
|
||||
|
||||
private Company company;
|
||||
|
||||
public User(String name, int age, Date birthday, Company company) {
|
||||
this.name = name;
|
||||
this.age = age;
|
||||
this.birthday = birthday;
|
||||
this.company = company;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public Company getCompany() {
|
||||
return company;
|
||||
}
|
||||
|
||||
public void setCompany(Company company) {
|
||||
this.company = company;
|
||||
}
|
||||
|
||||
public Date getBirthday() {
|
||||
return birthday;
|
||||
}
|
||||
|
||||
public void setBirthday(Date birthday) {
|
||||
this.birthday = birthday;
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
liteflow.rule-source=processFact/flow.xml
|
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<flow>
|
||||
<chain name="chain1">
|
||||
THEN(a);
|
||||
</chain>
|
||||
|
||||
<chain name="chain2">
|
||||
THEN(b);
|
||||
</chain>
|
||||
|
||||
<chain name="chain3">
|
||||
THEN(c);
|
||||
</chain>
|
||||
|
||||
<chain name="chain4">
|
||||
THEN(d);
|
||||
</chain>
|
||||
</flow>
|
|
@ -0,0 +1,97 @@
|
|||
package com.yomahub.liteflow.test.processFact;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.yomahub.liteflow.core.FlowExecutor;
|
||||
import com.yomahub.liteflow.flow.LiteflowResponse;
|
||||
import com.yomahub.liteflow.test.BaseTest;
|
||||
import com.yomahub.liteflow.test.processFact.context.*;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
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.junit.jupiter.SpringExtension;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* process方法上的fact映射参数测试
|
||||
* @author Bryan.Zhang
|
||||
*/
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@TestPropertySource(value = "classpath:/processFact/application.properties")
|
||||
@SpringBootTest(classes = ProcessFactELDeclSpringbootTest.class)
|
||||
@EnableAutoConfiguration
|
||||
@ComponentScan({"com.yomahub.liteflow.test.processFact.cmp"})
|
||||
public class ProcessFactELDeclSpringbootTest extends BaseTest {
|
||||
|
||||
@Resource
|
||||
private FlowExecutor flowExecutor;
|
||||
|
||||
// 最基本的情况
|
||||
@Test
|
||||
public void testFact1() throws Exception {
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg", createContext());
|
||||
Assertions.assertTrue(response.isSuccess());
|
||||
TestContext context = response.getContextBean(TestContext.class);
|
||||
Assertions.assertEquals("jack", context.getUser().getName());
|
||||
}
|
||||
|
||||
// 多上下文自动搜寻
|
||||
@Test
|
||||
public void testFact2() throws Exception {
|
||||
TestContext testContext = createContext();
|
||||
Demo1Context demo1Context = new Demo1Context();
|
||||
demo1Context.setData1("xxxx");
|
||||
demo1Context.setData2(99);
|
||||
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain2", "arg", demo1Context, testContext);
|
||||
Assertions.assertTrue(response.isSuccess());
|
||||
TestContext context = response.getContextBean(TestContext.class);
|
||||
Assertions.assertEquals(20, context.getUser().getCompany().getHeadCount());
|
||||
}
|
||||
|
||||
// 多上下文都有user,指定上下文中的user
|
||||
@Test
|
||||
public void testFact3() throws Exception {
|
||||
TestContext testContext = createContext();
|
||||
Demo2Context demo2Context = createDemo2Context();
|
||||
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain3", "arg", testContext, demo2Context);
|
||||
Assertions.assertTrue(response.isSuccess());
|
||||
Demo2Context context = response.getContextBean(Demo2Context.class);
|
||||
Assertions.assertEquals("rose", context.getUser().getName());
|
||||
}
|
||||
|
||||
// 多上下文都有user,指定上下文中的user
|
||||
@Test
|
||||
public void testFact4() throws Exception {
|
||||
Demo3Context demo3Context = createDemo3Context();
|
||||
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("chain4", "arg", demo3Context);
|
||||
Assertions.assertTrue(response.isSuccess());
|
||||
Demo3Context context = response.getContextBean(Demo3Context.class);
|
||||
Assertions.assertEquals("jelly", context.getUser().getName());
|
||||
}
|
||||
|
||||
private TestContext createContext(){
|
||||
Company company = new Company("XXX有限公司", "黄河路34号303室", 400);
|
||||
User user = new User("张三", 18, DateUtil.parseDate("1990-08-20"), company);
|
||||
return new TestContext(user, "this is data");
|
||||
}
|
||||
|
||||
private Demo2Context createDemo2Context(){
|
||||
Company company = new Company("XXX有限公司", "和平路12号101室", 600);
|
||||
User user = new User("李四", 28, DateUtil.parseDate("1990-06-01"), company);
|
||||
return new Demo2Context("xxx", user);
|
||||
}
|
||||
|
||||
private Demo3Context createDemo3Context(){
|
||||
Company company = new Company("XXX有限公司", "和平路12号101室", 600);
|
||||
User user = new User("王五", 28, DateUtil.parseDate("1990-06-01"), company);
|
||||
return new Demo3Context("xxx", user);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/**
|
||||
* <p>Title: liteflow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* @author Bryan.Zhang
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2020/4/1
|
||||
*/
|
||||
package com.yomahub.liteflow.test.processFact.cmp;
|
||||
|
||||
import com.yomahub.liteflow.annotation.LiteflowFact;
|
||||
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.processFact.context.User;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
|
||||
@Component("a")
|
||||
public class ACmp {
|
||||
|
||||
@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS, nodeType = NodeTypeEnum.COMMON)
|
||||
public void process(NodeComponent bindCmp,
|
||||
@LiteflowFact("user") User user,
|
||||
@LiteflowFact("user.company.address") String address) {
|
||||
user.setName("jack");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/**
|
||||
* <p>Title: liteflow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* @author Bryan.Zhang
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2020/4/1
|
||||
*/
|
||||
package com.yomahub.liteflow.test.processFact.cmp;
|
||||
|
||||
import com.yomahub.liteflow.annotation.LiteflowFact;
|
||||
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.processFact.context.Company;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component("b")
|
||||
public class BCmp {
|
||||
|
||||
@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS, nodeType = NodeTypeEnum.COMMON)
|
||||
public void process(NodeComponent bindCmp,
|
||||
@LiteflowFact("user.company") Company company,
|
||||
@LiteflowFact("data2") Integer data) {
|
||||
company.setHeadCount(20);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/**
|
||||
* <p>Title: liteflow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* @author Bryan.Zhang
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2020/4/1
|
||||
*/
|
||||
package com.yomahub.liteflow.test.processFact.cmp;
|
||||
|
||||
import com.yomahub.liteflow.annotation.LiteflowFact;
|
||||
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.processFact.context.User;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component("c")
|
||||
public class CCmp {
|
||||
|
||||
@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS, nodeType = NodeTypeEnum.COMMON)
|
||||
public void process(NodeComponent bindCmp,
|
||||
@LiteflowFact("demo2Context.user") User user) {
|
||||
user.setName("rose");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/**
|
||||
* <p>Title: liteflow</p>
|
||||
* <p>Description: 轻量级的组件式流程框架</p>
|
||||
* @author Bryan.Zhang
|
||||
* @email weenyc31@163.com
|
||||
* @Date 2020/4/1
|
||||
*/
|
||||
package com.yomahub.liteflow.test.processFact.cmp;
|
||||
|
||||
import com.yomahub.liteflow.annotation.LiteflowFact;
|
||||
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.processFact.context.User;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component("d")
|
||||
public class DCmp {
|
||||
|
||||
@LiteflowMethod(value = LiteFlowMethodEnum.PROCESS, nodeType = NodeTypeEnum.COMMON)
|
||||
public void process(NodeComponent bindCmp,
|
||||
@LiteflowFact("ctx.user") User user) {
|
||||
user.setName("jelly");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package com.yomahub.liteflow.test.processFact.context;
|
||||
|
||||
public class Company {
|
||||
|
||||
private String name;
|
||||
|
||||
private String address;
|
||||
|
||||
private int headCount;
|
||||
|
||||
public Company(String name, String address, int headCount) {
|
||||
this.name = name;
|
||||
this.address = address;
|
||||
this.headCount = headCount;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(String address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public int getHeadCount() {
|
||||
return headCount;
|
||||
}
|
||||
|
||||
public void setHeadCount(int headCount) {
|
||||
this.headCount = headCount;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package com.yomahub.liteflow.test.processFact.context;
|
||||
|
||||
public class Demo1Context {
|
||||
|
||||
private String data1;
|
||||
|
||||
private Integer data2;
|
||||
|
||||
public String getData1() {
|
||||
return data1;
|
||||
}
|
||||
|
||||
public void setData1(String data1) {
|
||||
this.data1 = data1;
|
||||
}
|
||||
|
||||
public Integer getData2() {
|
||||
return data2;
|
||||
}
|
||||
|
||||
public void setData2(Integer data2) {
|
||||
this.data2 = data2;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package com.yomahub.liteflow.test.processFact.context;
|
||||
|
||||
public class Demo2Context {
|
||||
|
||||
private String data1;
|
||||
|
||||
private User user;
|
||||
|
||||
public Demo2Context(String data1, User user) {
|
||||
this.data1 = data1;
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public String getData1() {
|
||||
return data1;
|
||||
}
|
||||
|
||||
public void setData1(String data1) {
|
||||
this.data1 = data1;
|
||||
}
|
||||
|
||||
public User getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public void setUser(User user) {
|
||||
this.user = user;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package com.yomahub.liteflow.test.processFact.context;
|
||||
|
||||
import com.yomahub.liteflow.context.ContextBean;
|
||||
|
||||
@ContextBean("ctx")
|
||||
public class Demo3Context {
|
||||
|
||||
private String data1;
|
||||
|
||||
private User user;
|
||||
|
||||
public Demo3Context(String data1, User user) {
|
||||
this.data1 = data1;
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public String getData1() {
|
||||
return data1;
|
||||
}
|
||||
|
||||
public void setData1(String data1) {
|
||||
this.data1 = data1;
|
||||
}
|
||||
|
||||
public User getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public void setUser(User user) {
|
||||
this.user = user;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package com.yomahub.liteflow.test.processFact.context;
|
||||
|
||||
public class TestContext {
|
||||
|
||||
private User user;
|
||||
|
||||
private String data1;
|
||||
|
||||
public TestContext(User user, String data1) {
|
||||
this.user = user;
|
||||
this.data1 = data1;
|
||||
}
|
||||
|
||||
public User getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public void setUser(User user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
public String getData1() {
|
||||
return data1;
|
||||
}
|
||||
|
||||
public void setData1(String data1) {
|
||||
this.data1 = data1;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package com.yomahub.liteflow.test.processFact.context;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public class User {
|
||||
|
||||
private String name;
|
||||
|
||||
private int age;
|
||||
|
||||
private Date birthday;
|
||||
|
||||
private Company company;
|
||||
|
||||
public User(String name, int age, Date birthday, Company company) {
|
||||
this.name = name;
|
||||
this.age = age;
|
||||
this.birthday = birthday;
|
||||
this.company = company;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public Company getCompany() {
|
||||
return company;
|
||||
}
|
||||
|
||||
public void setCompany(Company company) {
|
||||
this.company = company;
|
||||
}
|
||||
|
||||
public Date getBirthday() {
|
||||
return birthday;
|
||||
}
|
||||
|
||||
public void setBirthday(Date birthday) {
|
||||
this.birthday = birthday;
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
liteflow.rule-source=processFact/flow.xml
|
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<flow>
|
||||
<chain name="chain1">
|
||||
THEN(a);
|
||||
</chain>
|
||||
|
||||
<chain name="chain2">
|
||||
THEN(b);
|
||||
</chain>
|
||||
|
||||
<chain name="chain3">
|
||||
THEN(c);
|
||||
</chain>
|
||||
|
||||
<chain name="chain4">
|
||||
THEN(d);
|
||||
</chain>
|
||||
</flow>
|
Loading…
Reference in New Issue