mirror of
https://gitee.com/dromara/liteFlow.git
synced 2026-05-14 12:12:08 +08:00
future #I9050W 为每一个上下文提供一个名字,使用时可以根据名字来获取
This commit is contained in:
@@ -280,6 +280,10 @@ public abstract class NodeComponent {
|
|||||||
return this.getSlot().getContextBean(contextBeanClazz);
|
return this.getSlot().getContextBean(contextBeanClazz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public <T> T getContextBean(String contextName) {
|
||||||
|
return this.getSlot().getContextBean(contextName);
|
||||||
|
}
|
||||||
|
|
||||||
public String getNodeId() {
|
public String getNodeId() {
|
||||||
return nodeId;
|
return nodeId;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,6 +101,10 @@ public class LiteflowResponse {
|
|||||||
return this.getSlot().getContextBean(contextBeanClazz);
|
return this.getSlot().getContextBean(contextBeanClazz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public <T> T getContextBean(String contextName) {
|
||||||
|
return this.getSlot().getContextBean(contextName);
|
||||||
|
}
|
||||||
|
|
||||||
public Map<String, List<CmpStep>> getExecuteSteps() {
|
public Map<String, List<CmpStep>> getExecuteSteps() {
|
||||||
Map<String, List<CmpStep>> map = new LinkedHashMap<>();
|
Map<String, List<CmpStep>> map = new LinkedHashMap<>();
|
||||||
this.getSlot().getExecuteSteps().forEach(cmpStep -> {
|
this.getSlot().getExecuteSteps().forEach(cmpStep -> {
|
||||||
|
|||||||
@@ -54,17 +54,7 @@ public abstract class ScriptExecutor {
|
|||||||
// key的规则为自定义上下文的simpleName
|
// key的规则为自定义上下文的simpleName
|
||||||
// 比如你的自定义上下文为AbcContext,那么key就为:abcContext
|
// 比如你的自定义上下文为AbcContext,那么key就为:abcContext
|
||||||
// 这里不统一放一个map的原因是考虑到有些用户会调用上下文里的方法,而不是参数,所以脚本语言的绑定表里也是放多个上下文
|
// 这里不统一放一个map的原因是考虑到有些用户会调用上下文里的方法,而不是参数,所以脚本语言的绑定表里也是放多个上下文
|
||||||
DataBus.getContextBeanList(wrap.getSlotIndex()).forEach(o -> {
|
DataBus.getContextBeanList(wrap.getSlotIndex()).forEach(tuple -> putConsumer.accept(tuple.get(0), tuple.get(1)));
|
||||||
ContextBean contextBean = AnnoUtil.getAnnotation(o.getClass(), ContextBean.class);
|
|
||||||
String key;
|
|
||||||
if (contextBean != null && contextBean.value().trim().length() > 0) {
|
|
||||||
key = contextBean.value();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
key = StrUtil.lowerFirst(o.getClass().getSimpleName());
|
|
||||||
}
|
|
||||||
putConsumer.accept(key, o);
|
|
||||||
});
|
|
||||||
|
|
||||||
// 把wrap对象转换成元数据map
|
// 把wrap对象转换成元数据map
|
||||||
Map<String, Object> metaMap = BeanUtil.beanToMap(wrap);
|
Map<String, Object> metaMap = BeanUtil.beanToMap(wrap);
|
||||||
|
|||||||
@@ -7,10 +7,14 @@
|
|||||||
*/
|
*/
|
||||||
package com.yomahub.liteflow.slot;
|
package com.yomahub.liteflow.slot;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.Tuple;
|
||||||
import cn.hutool.core.map.MapUtil;
|
import cn.hutool.core.map.MapUtil;
|
||||||
import cn.hutool.core.util.BooleanUtil;
|
import cn.hutool.core.util.BooleanUtil;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.core.util.ReflectUtil;
|
import cn.hutool.core.util.ReflectUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import com.yomahub.liteflow.annotation.util.AnnoUtil;
|
||||||
|
import com.yomahub.liteflow.context.ContextBean;
|
||||||
import com.yomahub.liteflow.log.LFLog;
|
import com.yomahub.liteflow.log.LFLog;
|
||||||
import com.yomahub.liteflow.log.LFLoggerManager;
|
import com.yomahub.liteflow.log.LFLoggerManager;
|
||||||
import com.yomahub.liteflow.property.LiteflowConfig;
|
import com.yomahub.liteflow.property.LiteflowConfig;
|
||||||
@@ -74,13 +78,22 @@ public class DataBus {
|
|||||||
.map((Function<Class<?>, Object>) ReflectUtil::newInstanceIfPossible)
|
.map((Function<Class<?>, Object>) ReflectUtil::newInstanceIfPossible)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
Slot slot = new Slot(contextBeanList);
|
return offerSlotByBean(contextBeanList);
|
||||||
|
|
||||||
return offerIndex(slot);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int offerSlotByBean(List<Object> contextList) {
|
public static int offerSlotByBean(List<Object> contextList) {
|
||||||
Slot slot = new Slot(contextList);
|
List<Tuple> contextBeanList = contextList.stream().map(object -> {
|
||||||
|
ContextBean contextBean = AnnoUtil.getAnnotation(object.getClass(), ContextBean.class);
|
||||||
|
String contextKey;
|
||||||
|
if (contextBean != null && StrUtil.isNotBlank(contextBean.value())){
|
||||||
|
contextKey = contextBean.value();
|
||||||
|
}else{
|
||||||
|
contextKey = StrUtil.lowerFirst(object.getClass().getSimpleName());
|
||||||
|
}
|
||||||
|
return new Tuple(contextKey, object);
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
|
||||||
|
Slot slot = new Slot(contextBeanList);
|
||||||
|
|
||||||
return offerIndex(slot);
|
return offerIndex(slot);
|
||||||
}
|
}
|
||||||
@@ -128,7 +141,7 @@ public class DataBus {
|
|||||||
return SLOTS.get(slotIndex);
|
return SLOTS.get(slotIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<Object> getContextBeanList(int slotIndex) {
|
public static List<Tuple> getContextBeanList(int slotIndex) {
|
||||||
Slot slot = getSlot(slotIndex);
|
Slot slot = getSlot(slotIndex);
|
||||||
return slot.getContextBeanList();
|
return slot.getContextBeanList();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ package com.yomahub.liteflow.slot;
|
|||||||
|
|
||||||
import cn.hutool.core.collection.ConcurrentHashSet;
|
import cn.hutool.core.collection.ConcurrentHashSet;
|
||||||
import cn.hutool.core.collection.ListUtil;
|
import cn.hutool.core.collection.ListUtil;
|
||||||
|
import cn.hutool.core.lang.Tuple;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.alibaba.ttl.TransmittableThreadLocal;
|
import com.alibaba.ttl.TransmittableThreadLocal;
|
||||||
@@ -30,6 +31,7 @@ import java.util.Set;
|
|||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentLinkedDeque;
|
import java.util.concurrent.ConcurrentLinkedDeque;
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Slot的抽象类实现
|
* Slot的抽象类实现
|
||||||
@@ -91,14 +93,14 @@ public class Slot {
|
|||||||
|
|
||||||
protected ConcurrentHashMap<String, Object> metaDataMap = new ConcurrentHashMap<>();
|
protected ConcurrentHashMap<String, Object> metaDataMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private List<Object> contextBeanList;
|
private List<Tuple> contextBeanList;
|
||||||
|
|
||||||
private static final TransmittableThreadLocal<Deque<Condition>> conditionStack = TransmittableThreadLocal.withInitial(ConcurrentLinkedDeque::new);
|
private static final TransmittableThreadLocal<Deque<Condition>> conditionStack = TransmittableThreadLocal.withInitial(ConcurrentLinkedDeque::new);
|
||||||
|
|
||||||
public Slot() {
|
public Slot() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Slot(List<Object> contextBeanList) {
|
public Slot(List<Tuple> contextBeanList) {
|
||||||
this.contextBeanList = contextBeanList;
|
this.contextBeanList = contextBeanList;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -449,21 +451,30 @@ public class Slot {
|
|||||||
metaDataMap.remove(SUB_EXCEPTION_PREFIX + chainId);
|
metaDataMap.remove(SUB_EXCEPTION_PREFIX + chainId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Object> getContextBeanList() {
|
public List<Tuple> getContextBeanList() {
|
||||||
return this.contextBeanList;
|
return this.contextBeanList;
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> T getContextBean(Class<T> contextBeanClazz) {
|
public <T> T getContextBean(Class<T> contextBeanClazz) {
|
||||||
T t = (T) contextBeanList.stream().filter(o -> o.getClass().getName().equals(contextBeanClazz.getName())).findFirst().orElse(null);
|
Tuple contextTuple = contextBeanList.stream().filter(tuple -> tuple.get(1).getClass().getName().equals(contextBeanClazz.getName())).findFirst().orElse(null);
|
||||||
if (t == null) {
|
if (contextTuple == null) {
|
||||||
contextBeanList.forEach(o -> LOG.info("ChainId[{}], Context class:{},Request class:{}", this.getChainId(), o.getClass().getName(), contextBeanClazz.getName()));
|
contextBeanList.forEach(o -> LOG.info("ChainId[{}], Context class:{},Request class:{}", this.getChainId(), o.getClass().getName(), contextBeanClazz.getName()));
|
||||||
throw new NoSuchContextBeanException("this type is not in the context type passed in");
|
throw new NoSuchContextBeanException("this type is not in the context type passed in");
|
||||||
}
|
}
|
||||||
return t;
|
return contextTuple.get(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> T getContextBean(String contextBeanKey) {
|
||||||
|
Tuple contextTuple = contextBeanList.stream().filter(tuple -> tuple.get(0).equals(contextBeanKey)).findFirst().orElse(null);
|
||||||
|
if (contextTuple == null) {
|
||||||
|
contextBeanList.forEach(o -> LOG.info("ChainId[{}], Context class:{},Request contextBeanKey:{}", this.getChainId(), o.getClass().getName(), contextBeanKey));
|
||||||
|
throw new NoSuchContextBeanException("this context key is not defined");
|
||||||
|
}
|
||||||
|
return contextTuple.get(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> T getFirstContextBean() {
|
public <T> T getFirstContextBean() {
|
||||||
Class<T> firstContextBeanClazz = (Class<T>) this.getContextBeanList().get(0).getClass();
|
Class<T> firstContextBeanClazz = (Class<T>) this.getContextBeanList().get(0).get(1).getClass();
|
||||||
return this.getContextBean(firstContextBeanClazz);
|
return this.getContextBean(firstContextBeanClazz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package com.yomahub.liteflow.test.contextBean;
|
||||||
|
|
||||||
|
import com.yomahub.liteflow.core.FlowExecutor;
|
||||||
|
import com.yomahub.liteflow.flow.LiteflowResponse;
|
||||||
|
import com.yomahub.liteflow.test.BaseTest;
|
||||||
|
import com.yomahub.liteflow.test.contextBean.context.TestContext;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
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 javax.annotation.Resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ContextBean测试
|
||||||
|
*
|
||||||
|
* @author Bryan.Zhang
|
||||||
|
*/
|
||||||
|
@TestPropertySource(value = "classpath:/contextBean/application.properties")
|
||||||
|
@SpringBootTest(classes = ContextBeanSpringbootTest.class)
|
||||||
|
@EnableAutoConfiguration
|
||||||
|
@ComponentScan({ "com.yomahub.liteflow.test.contextBean.cmp" })
|
||||||
|
public class ContextBeanSpringbootTest extends BaseTest {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private FlowExecutor flowExecutor;
|
||||||
|
|
||||||
|
// 最简单的情况
|
||||||
|
@Test
|
||||||
|
public void testContextBean1() throws Exception {
|
||||||
|
LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg", TestContext.class);
|
||||||
|
Assertions.assertTrue(response.isSuccess());
|
||||||
|
TestContext context = response.getContextBean("skuContext");
|
||||||
|
Assertions.assertEquals("J001", context.getSkuCode());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* <p>Title: liteflow</p>
|
||||||
|
* <p>Description: 轻量级的组件式流程框架</p>
|
||||||
|
* @author Bryan.Zhang
|
||||||
|
* @email weenyc31@163.com
|
||||||
|
* @Date 2020/4/1
|
||||||
|
*/
|
||||||
|
package com.yomahub.liteflow.test.contextBean.cmp;
|
||||||
|
|
||||||
|
import com.yomahub.liteflow.core.NodeComponent;
|
||||||
|
import com.yomahub.liteflow.test.contextBean.context.TestContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component("a")
|
||||||
|
public class ACmp extends NodeComponent {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void process() {
|
||||||
|
TestContext context = this.getContextBean("skuContext");
|
||||||
|
context.setSkuCode("J001");
|
||||||
|
System.out.println("ACmp executed!");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
/**
|
||||||
|
* <p>Title: liteflow</p>
|
||||||
|
* <p>Description: 轻量级的组件式流程框架</p>
|
||||||
|
* @author Bryan.Zhang
|
||||||
|
* @email weenyc31@163.com
|
||||||
|
* @Date 2020/4/1
|
||||||
|
*/
|
||||||
|
package com.yomahub.liteflow.test.contextBean.cmp;
|
||||||
|
|
||||||
|
import com.yomahub.liteflow.core.NodeComponent;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component("b")
|
||||||
|
public class BCmp extends NodeComponent {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void process() {
|
||||||
|
System.out.println("BCmp executed!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package com.yomahub.liteflow.test.contextBean.context;
|
||||||
|
|
||||||
|
import com.yomahub.liteflow.context.ContextBean;
|
||||||
|
|
||||||
|
@ContextBean("skuContext")
|
||||||
|
public class TestContext {
|
||||||
|
|
||||||
|
private String skuCode;
|
||||||
|
|
||||||
|
private String skuName;
|
||||||
|
|
||||||
|
public TestContext(String skuCode, String skuName) {
|
||||||
|
this.skuCode = skuCode;
|
||||||
|
this.skuName = skuName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSkuCode() {
|
||||||
|
return skuCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSkuCode(String skuCode) {
|
||||||
|
this.skuCode = skuCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSkuName() {
|
||||||
|
return skuName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSkuName(String skuName) {
|
||||||
|
this.skuName = skuName;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
liteflow.rule-source=contextBean/flow.xml
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE flow PUBLIC "liteflow" "liteflow.dtd">
|
||||||
|
<flow>
|
||||||
|
<chain name="chain1">
|
||||||
|
THEN(a,b);
|
||||||
|
</chain>
|
||||||
|
</flow>
|
||||||
Reference in New Issue
Block a user