future #I9050W 为每一个上下文提供一个名字,使用时可以根据名字来获取
This commit is contained in:
parent
c373fd78cd
commit
69b7fdf991
|
@ -280,6 +280,10 @@ public abstract class NodeComponent {
|
|||
return this.getSlot().getContextBean(contextBeanClazz);
|
||||
}
|
||||
|
||||
public <T> T getContextBean(String contextName) {
|
||||
return this.getSlot().getContextBean(contextName);
|
||||
}
|
||||
|
||||
public String getNodeId() {
|
||||
return nodeId;
|
||||
}
|
||||
|
|
|
@ -101,6 +101,10 @@ public class LiteflowResponse {
|
|||
return this.getSlot().getContextBean(contextBeanClazz);
|
||||
}
|
||||
|
||||
public <T> T getContextBean(String contextName) {
|
||||
return this.getSlot().getContextBean(contextName);
|
||||
}
|
||||
|
||||
public Map<String, List<CmpStep>> getExecuteSteps() {
|
||||
Map<String, List<CmpStep>> map = new LinkedHashMap<>();
|
||||
this.getSlot().getExecuteSteps().forEach(cmpStep -> {
|
||||
|
|
|
@ -54,17 +54,7 @@ public abstract class ScriptExecutor {
|
|||
// key的规则为自定义上下文的simpleName
|
||||
// 比如你的自定义上下文为AbcContext,那么key就为:abcContext
|
||||
// 这里不统一放一个map的原因是考虑到有些用户会调用上下文里的方法,而不是参数,所以脚本语言的绑定表里也是放多个上下文
|
||||
DataBus.getContextBeanList(wrap.getSlotIndex()).forEach(o -> {
|
||||
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);
|
||||
});
|
||||
DataBus.getContextBeanList(wrap.getSlotIndex()).forEach(tuple -> putConsumer.accept(tuple.get(0), tuple.get(1)));
|
||||
|
||||
// 把wrap对象转换成元数据map
|
||||
Map<String, Object> metaMap = BeanUtil.beanToMap(wrap);
|
||||
|
|
|
@ -7,10 +7,14 @@
|
|||
*/
|
||||
package com.yomahub.liteflow.slot;
|
||||
|
||||
import cn.hutool.core.lang.Tuple;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.BooleanUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
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.LFLoggerManager;
|
||||
import com.yomahub.liteflow.property.LiteflowConfig;
|
||||
|
@ -74,13 +78,22 @@ public class DataBus {
|
|||
.map((Function<Class<?>, Object>) ReflectUtil::newInstanceIfPossible)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
Slot slot = new Slot(contextBeanList);
|
||||
|
||||
return offerIndex(slot);
|
||||
return offerSlotByBean(contextBeanList);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -128,7 +141,7 @@ public class DataBus {
|
|||
return SLOTS.get(slotIndex);
|
||||
}
|
||||
|
||||
public static List<Object> getContextBeanList(int slotIndex) {
|
||||
public static List<Tuple> getContextBeanList(int slotIndex) {
|
||||
Slot slot = getSlot(slotIndex);
|
||||
return slot.getContextBeanList();
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ package com.yomahub.liteflow.slot;
|
|||
|
||||
import cn.hutool.core.collection.ConcurrentHashSet;
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import cn.hutool.core.lang.Tuple;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.alibaba.ttl.TransmittableThreadLocal;
|
||||
|
@ -30,6 +31,7 @@ import java.util.Set;
|
|||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedDeque;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* Slot的抽象类实现
|
||||
|
@ -91,14 +93,14 @@ public class Slot {
|
|||
|
||||
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);
|
||||
|
||||
public Slot() {
|
||||
}
|
||||
|
||||
public Slot(List<Object> contextBeanList) {
|
||||
public Slot(List<Tuple> contextBeanList) {
|
||||
this.contextBeanList = contextBeanList;
|
||||
}
|
||||
|
||||
|
@ -449,21 +451,30 @@ public class Slot {
|
|||
metaDataMap.remove(SUB_EXCEPTION_PREFIX + chainId);
|
||||
}
|
||||
|
||||
public List<Object> getContextBeanList() {
|
||||
public List<Tuple> getContextBeanList() {
|
||||
return this.contextBeanList;
|
||||
}
|
||||
|
||||
public <T> T getContextBean(Class<T> contextBeanClazz) {
|
||||
T t = (T) contextBeanList.stream().filter(o -> o.getClass().getName().equals(contextBeanClazz.getName())).findFirst().orElse(null);
|
||||
if (t == null) {
|
||||
Tuple contextTuple = contextBeanList.stream().filter(tuple -> tuple.get(1).getClass().getName().equals(contextBeanClazz.getName())).findFirst().orElse(null);
|
||||
if (contextTuple == null) {
|
||||
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");
|
||||
}
|
||||
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() {
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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>
|
Loading…
Reference in New Issue