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; }