diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/agentcenter/AgentCenterController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/agentcenter/AgentCenterController.java index fe1f681..1453d80 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/agentcenter/AgentCenterController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/agentcenter/AgentCenterController.java @@ -62,7 +62,7 @@ public class AgentCenterController extends BaseController { return NSSDKServer.Fail(e.getErrno(), e.getMessage()); } - catch(IllegalArgumentException e) + catch(Exception e) { return NSSDKServer.Fail(NSErrno.ERRNO_ERROR, e.getMessage()); } diff --git a/ruoyi-agentcenter/src/main/java/com/ruoyi/agentcenter/listener/ContractionListener.java b/ruoyi-agentcenter/src/main/java/com/ruoyi/agentcenter/listener/ContractionListener.java index b50450f..0006f20 100644 --- a/ruoyi-agentcenter/src/main/java/com/ruoyi/agentcenter/listener/ContractionListener.java +++ b/ruoyi-agentcenter/src/main/java/com/ruoyi/agentcenter/listener/ContractionListener.java @@ -3,6 +3,7 @@ package com.ruoyi.agentcenter.listener; import cn.hutool.core.lang.Assert; import com.alibaba.fastjson2.JSONObject; import com.google.common.eventbus.Subscribe; +import com.nsgk.agentcentersdk.core.NSProtocol; import com.nsgk.agentcentersdk.entity.NSContractionEntity; import com.ruoyi.agentcenter.domain.TAgentContraction; import com.ruoyi.agentcenter.domain.TAgentTask; @@ -13,6 +14,8 @@ import com.ruoyi.agentcenter.service.ITAgentContractionService; import com.ruoyi.agentcenter.service.ITAgentTaskService; import com.ruoyi.common.core.domain.entity.SysDept; import com.ruoyi.common.utils.EventBusEngine; +import com.ruoyi.common.utils.handler.CallbackHandler; +import com.ruoyi.common.utils.handler.HandlerEngine; import com.ruoyi.common.utils.sql.SqlUtil; import com.ruoyi.system.service.ISysDeptService; import org.springframework.beans.factory.annotation.Autowired; @@ -34,11 +37,10 @@ public class ContractionListener @PostConstruct public void init() { - EventBusEngine.Register(this); + HandlerEngine.Register(this); } - @Subscribe - //@AllowConcurrentEvents + @CallbackHandler(protocol = NSProtocol.NS_PROTOCOL_CONTRACTION) public void handle(ContractionSession session) { TAgentContraction contraction = conv(session.message); diff --git a/ruoyi-agentcenter/src/main/java/com/ruoyi/agentcenter/service/impl/AgentCenterImpl.java b/ruoyi-agentcenter/src/main/java/com/ruoyi/agentcenter/service/impl/AgentCenterImpl.java index 570974f..dec7e18 100644 --- a/ruoyi-agentcenter/src/main/java/com/ruoyi/agentcenter/service/impl/AgentCenterImpl.java +++ b/ruoyi-agentcenter/src/main/java/com/ruoyi/agentcenter/service/impl/AgentCenterImpl.java @@ -16,6 +16,7 @@ import com.ruoyi.agentcenter.object.Session; import com.ruoyi.agentcenter.service.IAgentCenter; import com.ruoyi.common.config.RuoYiConfig; import com.ruoyi.common.utils.EventBusEngine; +import com.ruoyi.common.utils.handler.HandlerEngine; import org.springframework.stereotype.Service; import javax.servlet.http.HttpServletRequest; @@ -80,7 +81,7 @@ public class AgentCenterImpl implements IAgentCenter { Message message = getMessage(request); Session session = createSession(message); - EventBusEngine.Post(session); + HandlerEngine.Post(session); return session.result; } } diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/handler/CallbackHandler.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/handler/CallbackHandler.java new file mode 100644 index 0000000..b39640d --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/handler/CallbackHandler.java @@ -0,0 +1,23 @@ +package com.ruoyi.common.utils.handler; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 上报处理器 + * + * @author zhao + */ +@Target( ElementType.METHOD ) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface CallbackHandler +{ + /** + * 协议 + */ + public int protocol(); +} \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/handler/Handler.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/handler/Handler.java new file mode 100644 index 0000000..d669824 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/handler/Handler.java @@ -0,0 +1,134 @@ +package com.ruoyi.common.utils.handler; + +import cn.hutool.core.lang.Assert; +import cn.hutool.core.util.StrUtil; +import com.ruoyi.common.utils.spring.SpringUtils; + +import java.lang.reflect.Method; + +final class Handler +{ + public final int protocol; + public final Object handler; + public final Method method; + + public Handler(int protocol, Object handler, Method method) + { + this.protocol = protocol; + this.handler = handler; + this.method = method; + } + + public Handler(int protocol, Object handler, String methodName) + { + this.protocol = protocol; + this.handler = handler; + try + { + method = handler.getClass().getDeclaredMethod(methodName); + Class[] parameterTypes = method.getParameterTypes(); + if(parameterTypes.length < 1) + throw new RuntimeException("处理器函数参数至少有一个参数"); + } + catch(Exception e) + { + throw new RuntimeException(e); + } + } + + public Handler(int protocol, String beanName, String methodName) + { + this.protocol = protocol; + this.handler = SpringUtils.getBean(beanName); + try + { + method = handler.getClass().getDeclaredMethod(methodName); + Class[] parameterTypes = method.getParameterTypes(); + if(parameterTypes.length < 1) + throw new RuntimeException("处理器函数参数至少有一个参数"); + } + catch(Exception e) + { + throw new RuntimeException(e); + } + } + + public Handler(int protocol, Class beanClazz, String methodName) + { + this.protocol = protocol; + this.handler = SpringUtils.getBean(beanClazz); + try + { + method = handler.getClass().getDeclaredMethod(methodName); + } + catch(Exception e) + { + e.printStackTrace(); + throw new RuntimeException(e); + } + } + + public Object Invoke(Object...args) + { + Check(args); + if(!method.isAccessible()) + method.setAccessible(true); + try + { + return method.invoke(handler, args); + } + catch(Exception e) + { + e.printStackTrace(); + throw new RuntimeException(e); + } + } + + private void Check(Object...args) + { + String err = Match(args); + if(null != err) + throw new RuntimeException(err); + } + + public String Match(Object...args) + { + int argsLength = null != args ? args.length : 0; + Class[] parameterTypes = method.getParameterTypes(); + if(argsLength != parameterTypes.length) + return StrUtil.format("调用处理器函数参数数量不一致: 需要({})|实际({})", parameterTypes.length, argsLength); + for(int i = 0; i < argsLength; i++) + { + Class parameterType = parameterTypes[i]; + if(null == args[i]) + { + if(parameterType.equals(boolean.class) + || parameterType.equals(byte.class) + || parameterType.equals(short.class) + || parameterType.equals(int.class) + || parameterType.equals(long.class) + || parameterType.equals(float.class) + || parameterType.equals(double.class) + || parameterType.equals(char.class) + ) + return StrUtil.format("调用处理器函数第{}个参数传参为null, 但实参是基本数据类型", i + 1); + } + else + { + if(!parameterType.isAssignableFrom(args[i].getClass())) + return StrUtil.format("调用处理器函数第{}个参数传参与实参类型不一致: 需要({})|实际({})", i + 1, parameterType.getName(), args[i].getClass().getName()); + } + } + return null; + } + + @Override + public String toString() + { + return "Handler{" + + "protocol=" + protocol + + ", handler=" + handler + + ", method=" + method + + '}'; + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/handler/HandlerEngine.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/handler/HandlerEngine.java new file mode 100644 index 0000000..d78e480 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/handler/HandlerEngine.java @@ -0,0 +1,139 @@ +package com.ruoyi.common.utils.handler; + +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.lang.Assert; +import com.google.common.eventbus.EventBus; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; + +import javax.annotation.PreDestroy; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +@Component +public final class HandlerEngine +{ + private static final Logger logger = LoggerFactory.getLogger("HandlerEngine" ); + private static final List _listenerList = new ArrayList<>(); + private static final Map _handlerMap = new HashMap<>(); + + public static Object Post(Object...message) + { + Handler handler = _handlerMap.values().stream().filter((x) -> null == x.Match(message)).findFirst().orElse(null); + Assert.notNull(handler, "没有对应处理器被注册"); + return handler.Invoke(message); + } + + @SuppressWarnings("unchecked") + public static T PostT(Object...message) + { + return (T)Post(message); + } + + public static Object Run(int protocol, Object...message) + { + Handler handler = _handlerMap.get(protocol); + Assert.notNull(handler, "协议对应的处理器不存在: {}", protocol); + return handler.Invoke(message); + } + + @SuppressWarnings("unchecked") + public static T RunT(int protocol, Object...message) + { + return (T)Run(protocol, message); + } + + public static void Register(Object listener) + { + if(null == listener) + return; + synchronized(_listenerList) { + if(_listenerList.contains(listener)) + return; + List handlers = parseObject(listener); + if(CollectionUtil.isEmpty(handlers)) + return; + if(handlers.stream().anyMatch((x) -> _handlerMap.containsKey(x.protocol))) + return; + for(Handler handler : handlers) + { + _handlerMap.put(handler.protocol, handler); + logger.info("Register -> " + handler); + } + _listenerList.add(listener); + logger.info("HandlerEngine::Register -> " + listener); + } + } + + public static void Unregister(Object listener) + { + if(null == listener) + return; + synchronized(_listenerList) { + if(!_listenerList.contains(listener)) + return; + List rm = new ArrayList<>(); + _handlerMap.forEach((k, v) -> { + if(v.handler == listener) + { + rm.add(k); + logger.info("Unregister -> " + v); + } + }); + rm.forEach(_handlerMap::remove); + _listenerList.remove(listener); + logger.info("HandlerEngine::Unregister -> " + listener); + } + } + + @PreDestroy + public static void UnregisterAll() + { + synchronized(_listenerList) { + logger.info("HandlerEngine::UnregisterAll -> " + _listenerList.size()); + _handlerMap.clear(); + _listenerList.clear(); + } + } + + private static List parseObject(Object obj) + { + if(null == obj) + return null; + Class clazz = obj.getClass(); + return parseObject(obj, clazz); + } + + private static List parseObject(Object obj, Class clazz) + { + if(null == clazz) + return null; + List list = new ArrayList<>(); + Method[] declaredMethods = clazz.getDeclaredMethods(); + for(Method method : declaredMethods) + { + CallbackHandler annotation = method.getAnnotation(CallbackHandler.class); + if(null == annotation) + continue; + int protocol = annotation.protocol(); + Handler handler = new Handler(protocol, obj, method); + list.add(handler); + } + Class superclass = clazz.getSuperclass(); + if(null != superclass && !Object.class.equals(superclass)) + { + List handlers = parseObject(obj, superclass); + if(CollectionUtil.isNotEmpty(handlers)) + list.addAll(handlers); + } + return list; + } +}