package com.pacmp.utils;
import lombok.extern.slf4j.Slf4j; import org.apache.dubbo.config.ApplicationConfig; import org.apache.dubbo.config.ReferenceConfig; import org.apache.dubbo.config.RegistryConfig; import org.apache.dubbo.config.utils.ReferenceConfigCache; import org.apache.dubbo.rpc.service.GenericService; import org.springframework.beans.factory.annotation.Value; import java.util.List; import java.util.Map; /** * @Author xxx * @Date 2020/6/2 18:28 * @Version 1.0 * @Description dubbo泛化调用 */ @Slf4j public class DubboServiceFactory { private ApplicationConfig application; private RegistryConfig registry; @Value("${dubbo.registry.address}") private String address; @Value("${dubbo.application.name}") private String name; private static class SingletonHolder { private static DubboServiceFactory INSTANCE = new DubboServiceFactory(); } private DubboServiceFactory(){ try { ApplicationConfig applicationConfig = new ApplicationConfig(); applicationConfig.setName(name); RegistryConfig registryConfig = new RegistryConfig(); registryConfig.setAddress(address); this.application = applicationConfig; this.registry = registryConfig; }catch (Exception e){ log.error("DubboServiceFactory",e); e.printStackTrace(); } } public static DubboServiceFactory getInstance() { return SingletonHolder.INSTANCE; } public Object genericInvoke(String interfaceClass, String methodName, List<Map<String, Object>> parameters){ try { ReferenceConfig<GenericService> reference = new ReferenceConfig<GenericService>(); reference.setApplication(application); reference.setRegistry(registry); reference.setInterface(interfaceClass); // 接口名 reference.setGeneric(true); // 声明为泛化接口 //ReferenceConfig实例很重,封装了与注册中心的连接以及与提供者的连接, //需要缓存,否则重复生成ReferenceConfig可能造成性能问题并且会有内存和连接泄漏。 //API方式编程时,容易忽略此问题。 //这里使用dubbo内置的简单缓存工具类进行缓存 ReferenceConfigCache cache = ReferenceConfigCache.getCache(); GenericService genericService = cache.get(reference); // 用org.apache.dubbo.rpc.service.GenericService可以替代所有接口引用 int len = parameters.size(); String[] invokeParamTyeps = new String[len]; Object[] invokeParams = new Object[len]; for (int i = 0; i < len; i++) { invokeParamTyeps[i] = parameters.get(i).get("ParamType") + ""; invokeParams[i] = parameters.get(i).get("Object"); } return genericService.$invoke(methodName, invokeParamTyeps, invokeParams); }catch (Exception e){ log.error("genericInvoke",e); e.printStackTrace(); } return "500"; } }
调用示例
@RequestMapping("/router") public Object router(HttpServletRequest request,@RequestBody RequestData requestData) { LinkedHashMap requestParams= (LinkedHashMap) requestData.getRequestParams(); Map map = new HashMap<>(); List<Map<String, Object>> paramInfos= new ArrayList<>(); map.put("ParamType", "java.lang.Object"); //后端接口参数类型 map.put("Object", requestParams); //用以调用后端接口的实参 paramInfos.add(map); DubboServiceFactory dubbo = DubboServiceFactory.getInstance(); Object result = dubbo.genericInvoke(requestData.getInterfaceName(), requestData.getMethodName(), paramInfos); return result; }