diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/annotation/util/AnnoUtil.java b/liteflow-core/src/main/java/com/yomahub/liteflow/annotation/util/AnnoUtil.java
index 45e1e2382..09fb5362f 100644
--- a/liteflow-core/src/main/java/com/yomahub/liteflow/annotation/util/AnnoUtil.java
+++ b/liteflow-core/src/main/java/com/yomahub/liteflow/annotation/util/AnnoUtil.java
@@ -44,7 +44,7 @@ public class AnnoUtil {
return annotation;
}
- public static Object getDefaultValue(Class annotationType, String property){
+ private static Object getDefaultValue(Class annotationType, String property){
try{
return annotationType.getMethod(property).getDefaultValue();
}catch (Exception e){
diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/exception/ScriptBeanMethodInvokeException.java b/liteflow-core/src/main/java/com/yomahub/liteflow/exception/ScriptBeanMethodInvokeException.java
new file mode 100644
index 000000000..c65deb183
--- /dev/null
+++ b/liteflow-core/src/main/java/com/yomahub/liteflow/exception/ScriptBeanMethodInvokeException.java
@@ -0,0 +1,29 @@
+package com.yomahub.liteflow.exception;
+
+/**
+ * ScriptBean的方法无法被调用异常
+ * @author Bryan.Zhang
+ */
+public class ScriptBeanMethodInvokeException extends RuntimeException {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 异常信息
+ */
+ private String message;
+
+ public ScriptBeanMethodInvokeException(String message) {
+ this.message = message;
+ }
+
+ @Override
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+}
diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/script/ScriptBean.java b/liteflow-core/src/main/java/com/yomahub/liteflow/script/annotation/ScriptBean.java
similarity index 51%
rename from liteflow-core/src/main/java/com/yomahub/liteflow/script/ScriptBean.java
rename to liteflow-core/src/main/java/com/yomahub/liteflow/script/annotation/ScriptBean.java
index e0dfbca0f..e99b9aa33 100644
--- a/liteflow-core/src/main/java/com/yomahub/liteflow/script/ScriptBean.java
+++ b/liteflow-core/src/main/java/com/yomahub/liteflow/script/annotation/ScriptBean.java
@@ -1,4 +1,6 @@
-package com.yomahub.liteflow.script;
+package com.yomahub.liteflow.script.annotation;
+
+import com.yomahub.liteflow.annotation.AliasFor;
import java.lang.annotation.*;
@@ -13,5 +15,13 @@ import java.lang.annotation.*;
@Inherited
public @interface ScriptBean {
+ @AliasFor("name")
String value() default "";
+
+ @AliasFor("value")
+ String name() default "";
+
+ String[] includeMethodName() default {};
+
+ String[] excludeMethodName() default {};
}
diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/script/jsr223/JSR223ScriptExecutor.java b/liteflow-core/src/main/java/com/yomahub/liteflow/script/jsr223/JSR223ScriptExecutor.java
index 4bd5c6b53..fced63a9f 100644
--- a/liteflow-core/src/main/java/com/yomahub/liteflow/script/jsr223/JSR223ScriptExecutor.java
+++ b/liteflow-core/src/main/java/com/yomahub/liteflow/script/jsr223/JSR223ScriptExecutor.java
@@ -98,7 +98,9 @@ public abstract class JSR223ScriptExecutor implements ScriptExecutor {
}catch (Exception e){
if (ObjectUtil.isNotNull(e.getCause()) && e.getCause() instanceof LiteFlowException){
throw (LiteFlowException)e.getCause();
- }else{
+ } else if (ObjectUtil.isNotNull(e.getCause()) && e.getCause() instanceof RuntimeException) {
+ throw (RuntimeException)e.getCause();
+ } else{
throw e;
}
}
diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/script/proxy/ScriptBeanProxy.java b/liteflow-core/src/main/java/com/yomahub/liteflow/script/proxy/ScriptBeanProxy.java
new file mode 100644
index 000000000..f5a5512b7
--- /dev/null
+++ b/liteflow-core/src/main/java/com/yomahub/liteflow/script/proxy/ScriptBeanProxy.java
@@ -0,0 +1,107 @@
+package com.yomahub.liteflow.script.proxy;
+
+import cn.hutool.core.collection.ListUtil;
+import cn.hutool.core.util.*;
+import com.yomahub.liteflow.exception.LiteFlowException;
+import com.yomahub.liteflow.exception.ScriptBeanMethodInvokeException;
+import com.yomahub.liteflow.script.annotation.ScriptBean;
+import com.yomahub.liteflow.util.LiteFlowProxyUtil;
+import com.yomahub.liteflow.util.SerialsUtil;
+import net.bytebuddy.ByteBuddy;
+import net.bytebuddy.implementation.InvocationHandlerAdapter;
+import net.bytebuddy.matcher.ElementMatchers;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class ScriptBeanProxy {
+
+ private final Logger LOG = LoggerFactory.getLogger(this.getClass());
+
+ private final Object bean;
+
+ private final Class> orignalClass;
+
+ private final ScriptBean scriptBeanAnno;
+
+ public ScriptBeanProxy(Object bean, Class> orignalClass, ScriptBean scriptBeanAnno) {
+ this.bean = bean;
+ this.orignalClass = orignalClass;
+ this.scriptBeanAnno = scriptBeanAnno;
+ }
+
+ public Object getProxyScriptBean(){
+ //获取bean里所有的method,包括超类里的
+ List methodNameList = Arrays.stream(orignalClass.getMethods()).map(Method::getName).collect(Collectors.toList());
+
+ //首先看@ScriptBean标注里的includeMethodName属性
+ //如果没有配置,则认为是全部的method,如果有配置,就取配置的method
+ if (ArrayUtil.isNotEmpty(scriptBeanAnno.includeMethodName())){
+ methodNameList = methodNameList.stream().filter(
+ methodName -> ListUtil.toList(scriptBeanAnno.includeMethodName()).contains(methodName)
+ ).collect(Collectors.toList());
+ }
+
+ //其次看excludeMethodName的配置
+ if (ArrayUtil.isNotEmpty(scriptBeanAnno.excludeMethodName())){
+ methodNameList = methodNameList.stream().filter(
+ methodName -> !ListUtil.toList(scriptBeanAnno.excludeMethodName()).contains(methodName)
+ ).collect(Collectors.toList());
+ }
+
+ try{
+ return new ByteBuddy().subclass(orignalClass)
+ .name(StrUtil.format("{}.ByteBuddy${}",
+ ClassUtil.getPackage(orignalClass),
+ SerialsUtil.generateShortUUID()))
+ .method(ElementMatchers.any())
+ .intercept(InvocationHandlerAdapter.of(new AopInvocationHandler(bean, methodNameList)))
+ .annotateType(orignalClass.getAnnotations())
+ .make()
+ .load(ScriptBeanProxy.class.getClassLoader())
+ .getLoaded()
+ .newInstance();
+ }catch (Exception e){
+ throw new LiteFlowException(e);
+ }
+
+ }
+
+ public class AopInvocationHandler implements InvocationHandler {
+
+ private final Object bean;
+
+ private final Class> clazz;
+
+ private final List canExecuteMethodNameList;
+
+ public AopInvocationHandler(Object bean, List canExecuteMethodNameList) {
+ this.bean = bean;
+ this.clazz = LiteFlowProxyUtil.getUserClass(bean.getClass());
+ this.canExecuteMethodNameList = canExecuteMethodNameList;
+ }
+
+ @Override
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ Method invokeMethod = Arrays.stream(clazz.getMethods()).filter(
+ m -> m.getName().equals(method.getName()) && m.getParameterCount() == method.getParameterCount()
+ ).findFirst().orElse(null);
+
+ if (invokeMethod == null){
+ String errorMsg = StrUtil.format("cannot find method[{}]", clazz.getName(), method.getName());
+ throw new ScriptBeanMethodInvokeException(errorMsg);
+ }
+
+ if (!canExecuteMethodNameList.contains(method.getName())){
+ String errorMsg = StrUtil.format("script bean method[{}.{}] cannot be executed", clazz.getName(), method.getName());
+ throw new ScriptBeanMethodInvokeException(errorMsg);
+ }
+
+ return invokeMethod.invoke(bean, args);
+ }
+ }
+}
diff --git a/liteflow-core/src/main/java/com/yomahub/liteflow/util/LiteFlowProxyUtil.java b/liteflow-core/src/main/java/com/yomahub/liteflow/util/LiteFlowProxyUtil.java
index 98d246479..c65faca1a 100644
--- a/liteflow-core/src/main/java/com/yomahub/liteflow/util/LiteFlowProxyUtil.java
+++ b/liteflow-core/src/main/java/com/yomahub/liteflow/util/LiteFlowProxyUtil.java
@@ -32,12 +32,7 @@ public class LiteFlowProxyUtil {
public static boolean isDeclareCmp(Class> clazz) {
//查看bean里的method是否有方法标记了@LiteflowMethod标注
//这里的bean有可能是cglib加强过的class,所以要先进行个判断
- Class> targetClass;
- if (isCglibProxyClass(clazz)) {
- targetClass = getUserClass(clazz);
- } else {
- targetClass = clazz;
- }
+ Class> targetClass = getUserClass(clazz);
// 判断是否有方法标记了@LiteflowMethod标注,有则为声明式组件
return Arrays.stream(targetClass.getMethods()).anyMatch(
method -> method.getAnnotation(LiteflowMethod.class) != null
diff --git a/liteflow-spring/src/main/java/com/yomahub/liteflow/spring/ComponentScanner.java b/liteflow-spring/src/main/java/com/yomahub/liteflow/spring/ComponentScanner.java
index 874f84b45..138a8a0e0 100644
--- a/liteflow-spring/src/main/java/com/yomahub/liteflow/spring/ComponentScanner.java
+++ b/liteflow-spring/src/main/java/com/yomahub/liteflow/spring/ComponentScanner.java
@@ -8,14 +8,15 @@
*/
package com.yomahub.liteflow.spring;
-import cn.hutool.core.annotation.AnnotationUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
+import com.yomahub.liteflow.annotation.util.AnnoUtil;
import com.yomahub.liteflow.aop.ICmpAroundAspect;
import com.yomahub.liteflow.core.NodeComponent;
import com.yomahub.liteflow.property.LiteflowConfig;
-import com.yomahub.liteflow.script.ScriptBean;
+import com.yomahub.liteflow.script.annotation.ScriptBean;
import com.yomahub.liteflow.script.ScriptBeanManager;
+import com.yomahub.liteflow.script.proxy.ScriptBeanProxy;
import com.yomahub.liteflow.util.LOGOPrinter;
import com.yomahub.liteflow.util.LiteFlowProxyUtil;
import org.slf4j.Logger;
@@ -61,7 +62,7 @@ public class ComponentScanner implements BeanPostProcessor {
@SuppressWarnings("rawtypes")
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
- Class clazz = bean.getClass();
+ Class clazz = LiteFlowProxyUtil.getUserClass(bean.getClass());
//判断是不是声明式组件
//如果是,就缓存到类属性的map中
@@ -98,9 +99,10 @@ public class ComponentScanner implements BeanPostProcessor {
}
//扫描@ScriptBean修饰的类
- ScriptBean scriptBean = AnnotationUtil.getAnnotation(bean.getClass(), ScriptBean.class);
+ ScriptBean scriptBean = AnnoUtil.getAnnotation(clazz, ScriptBean.class);
if (ObjectUtil.isNotNull(scriptBean)){
- ScriptBeanManager.addScriptBean(scriptBean.value(), bean);
+ ScriptBeanProxy proxy = new ScriptBeanProxy(bean, clazz, scriptBean);
+ ScriptBeanManager.addScriptBean(scriptBean.value(), proxy.getProxyScriptBean());
}
return bean;
diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-graaljs-springboot/src/test/java/com/yomahub/liteflow/test/script/graaljs/scriptbean/bean/DemoBean1.java b/liteflow-testcase-el/liteflow-testcase-el-script-graaljs-springboot/src/test/java/com/yomahub/liteflow/test/script/graaljs/scriptbean/bean/DemoBean1.java
index 77625ac01..5b63a16b4 100644
--- a/liteflow-testcase-el/liteflow-testcase-el-script-graaljs-springboot/src/test/java/com/yomahub/liteflow/test/script/graaljs/scriptbean/bean/DemoBean1.java
+++ b/liteflow-testcase-el/liteflow-testcase-el-script-graaljs-springboot/src/test/java/com/yomahub/liteflow/test/script/graaljs/scriptbean/bean/DemoBean1.java
@@ -1,6 +1,6 @@
package com.yomahub.liteflow.test.script.graaljs.scriptbean.bean;
-import com.yomahub.liteflow.script.ScriptBean;
+import com.yomahub.liteflow.script.annotation.ScriptBean;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/java/com/yomahub/liteflow/test/script/groovy/scriptbean/LiteFlowScriptScriptbeanGroovyELTest.java b/liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/java/com/yomahub/liteflow/test/script/groovy/scriptbean/LiteFlowScriptScriptbeanGroovyELTest.java
index b6039085f..6eee3a732 100644
--- a/liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/java/com/yomahub/liteflow/test/script/groovy/scriptbean/LiteFlowScriptScriptbeanGroovyELTest.java
+++ b/liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/java/com/yomahub/liteflow/test/script/groovy/scriptbean/LiteFlowScriptScriptbeanGroovyELTest.java
@@ -1,6 +1,7 @@
package com.yomahub.liteflow.test.script.groovy.scriptbean;
import com.yomahub.liteflow.core.FlowExecutor;
+import com.yomahub.liteflow.exception.ScriptBeanMethodInvokeException;
import com.yomahub.liteflow.flow.LiteflowResponse;
import com.yomahub.liteflow.slot.DefaultContext;
import com.yomahub.liteflow.test.BaseTest;
@@ -41,4 +42,37 @@ public class LiteFlowScriptScriptbeanGroovyELTest extends BaseTest {
Assert.assertEquals("hello,kobe", context.getData("demo"));
}
+ //测试scriptBean includeMethodName配置包含情况下
+ @Test
+ public void testScriptBean3() throws Exception{
+ LiteflowResponse response = flowExecutor.execute2Resp("chain3", "arg");
+ Assert.assertTrue(response.isSuccess());
+ DefaultContext context = response.getFirstContextBean();
+ Assert.assertEquals("hello,kobe", context.getData("demo"));
+ }
+
+ //测试scriptBean includeMethodName配置不包含情况下
+ @Test
+ public void testScriptBean4() throws Exception{
+ LiteflowResponse response = flowExecutor.execute2Resp("chain4", "arg");
+ Assert.assertFalse(response.isSuccess());
+ Assert.assertEquals(ScriptBeanMethodInvokeException.class, response.getCause().getClass());
+ }
+
+ //测试scriptBean excludeMethodName配置不包含情况下
+ @Test
+ public void testScriptBean5() throws Exception{
+ LiteflowResponse response = flowExecutor.execute2Resp("chain5", "arg");
+ Assert.assertTrue(response.isSuccess());
+ DefaultContext context = response.getFirstContextBean();
+ Assert.assertEquals("hello,kobe", context.getData("demo"));
+ }
+
+ //测试scriptBean excludeMethodName配置包含情况下
+ @Test
+ public void testScriptBean6() throws Exception{
+ LiteflowResponse response = flowExecutor.execute2Resp("chain6", "arg");
+ Assert.assertFalse(response.isSuccess());
+ Assert.assertEquals(ScriptBeanMethodInvokeException.class, response.getCause().getClass());
+ }
}
diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/java/com/yomahub/liteflow/test/script/groovy/scriptbean/bean/DemoBean1.java b/liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/java/com/yomahub/liteflow/test/script/groovy/scriptbean/bean/DemoBean1.java
index 5b04bb3c8..23fa5c252 100644
--- a/liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/java/com/yomahub/liteflow/test/script/groovy/scriptbean/bean/DemoBean1.java
+++ b/liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/java/com/yomahub/liteflow/test/script/groovy/scriptbean/bean/DemoBean1.java
@@ -1,6 +1,6 @@
package com.yomahub.liteflow.test.script.groovy.scriptbean.bean;
-import com.yomahub.liteflow.script.ScriptBean;
+import com.yomahub.liteflow.script.annotation.ScriptBean;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/java/com/yomahub/liteflow/test/script/groovy/scriptbean/bean/DemoBean3.java b/liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/java/com/yomahub/liteflow/test/script/groovy/scriptbean/bean/DemoBean3.java
new file mode 100644
index 000000000..37dcbc38f
--- /dev/null
+++ b/liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/java/com/yomahub/liteflow/test/script/groovy/scriptbean/bean/DemoBean3.java
@@ -0,0 +1,21 @@
+package com.yomahub.liteflow.test.script.groovy.scriptbean.bean;
+
+import com.yomahub.liteflow.script.annotation.ScriptBean;
+import org.springframework.stereotype.Component;
+
+@Component
+@ScriptBean(name = "demo3", includeMethodName = {"test1","test2"})
+public class DemoBean3 {
+
+ public String test1(String name){
+ return "hello,"+name;
+ }
+
+ public String test2(String name){
+ return "hello,"+name;
+ }
+
+ public String test3(String name){
+ return "hello,"+name;
+ }
+}
diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/java/com/yomahub/liteflow/test/script/groovy/scriptbean/bean/DemoBean4.java b/liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/java/com/yomahub/liteflow/test/script/groovy/scriptbean/bean/DemoBean4.java
new file mode 100644
index 000000000..34ac5075b
--- /dev/null
+++ b/liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/java/com/yomahub/liteflow/test/script/groovy/scriptbean/bean/DemoBean4.java
@@ -0,0 +1,21 @@
+package com.yomahub.liteflow.test.script.groovy.scriptbean.bean;
+
+import com.yomahub.liteflow.script.annotation.ScriptBean;
+import org.springframework.stereotype.Component;
+
+@Component
+@ScriptBean(name = "demo4", excludeMethodName = {"test2","test3"})
+public class DemoBean4 {
+
+ public String test1(String name){
+ return "hello,"+name;
+ }
+
+ public String test2(String name){
+ return "hello,"+name;
+ }
+
+ public String test3(String name){
+ return "hello,"+name;
+ }
+}
diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/resources/scriptbean/flow.xml b/liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/resources/scriptbean/flow.xml
index c9e22fa3e..397cff2c4 100644
--- a/liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/resources/scriptbean/flow.xml
+++ b/liteflow-testcase-el/liteflow-testcase-el-script-groovy-springboot/src/test/resources/scriptbean/flow.xml
@@ -15,6 +15,34 @@
defaultContext.setData("demo", str)
]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -24,4 +52,20 @@
THEN(a,b,c,e);
+
+
+ THEN(a,b,c,s1);
+
+
+
+ THEN(a,b,c,s2);
+
+
+
+ THEN(a,b,c,s3);
+
+
+
+ THEN(a,b,c,s4);
+
\ No newline at end of file
diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-javascript-springboot/src/test/java/com/yomahub/liteflow/test/script/javascript/scriptbean/bean/DemoBean1.java b/liteflow-testcase-el/liteflow-testcase-el-script-javascript-springboot/src/test/java/com/yomahub/liteflow/test/script/javascript/scriptbean/bean/DemoBean1.java
index 7cd387e7a..60bb7dba3 100644
--- a/liteflow-testcase-el/liteflow-testcase-el-script-javascript-springboot/src/test/java/com/yomahub/liteflow/test/script/javascript/scriptbean/bean/DemoBean1.java
+++ b/liteflow-testcase-el/liteflow-testcase-el-script-javascript-springboot/src/test/java/com/yomahub/liteflow/test/script/javascript/scriptbean/bean/DemoBean1.java
@@ -1,6 +1,6 @@
package com.yomahub.liteflow.test.script.javascript.scriptbean.bean;
-import com.yomahub.liteflow.script.ScriptBean;
+import com.yomahub.liteflow.script.annotation.ScriptBean;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
diff --git a/liteflow-testcase-el/liteflow-testcase-el-script-qlexpress-springboot/src/test/java/com/yomahub/liteflow/test/script/qlexpress/scriptbean/bean/DemoBean1.java b/liteflow-testcase-el/liteflow-testcase-el-script-qlexpress-springboot/src/test/java/com/yomahub/liteflow/test/script/qlexpress/scriptbean/bean/DemoBean1.java
index cf5e59093..5b6bc7704 100644
--- a/liteflow-testcase-el/liteflow-testcase-el-script-qlexpress-springboot/src/test/java/com/yomahub/liteflow/test/script/qlexpress/scriptbean/bean/DemoBean1.java
+++ b/liteflow-testcase-el/liteflow-testcase-el-script-qlexpress-springboot/src/test/java/com/yomahub/liteflow/test/script/qlexpress/scriptbean/bean/DemoBean1.java
@@ -1,6 +1,6 @@
package com.yomahub.liteflow.test.script.qlexpress.scriptbean.bean;
-import com.yomahub.liteflow.script.ScriptBean;
+import com.yomahub.liteflow.script.annotation.ScriptBean;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;