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