我们的系统采用是dubbo作为soa,但是如何动态调用dubbo接口呢?
1:MyReferenceUtils 类
@Component
public class MyReferenceUtils {
@Value("${dubbo.registry.address}")
private String registryAddress;
@Value("${dubbo.application.name}")
private String appllicationName;
/**
* 协议
*/
private static final String protocol = "zookeeper";
/**
* 不需要检测提供者
*/
private static final Boolean check = false;
/**
* 调用超时时间 毫秒
*/
private static final Integer timeout = 300000;
/**
* 获取缓存的MyReferenceConfig
*
* @param insterfaceName 接口全名
* @param version 版本号
* @return
*/
public GenericService getCacheGenericServiceByKey(String insterfaceName, String version) {
ReferenceConfigCache cache = ReferenceConfigCache.getCache();
ReferenceConfig<GenericService> referenceConfig = this.createReferenceConfig(appllicationName, registryAddress, protocol, check, timeout);
referenceConfig.setId(insterfaceName);
// 弱类型接口名
referenceConfig.setInterface(insterfaceName);
// 设置版本
referenceConfig.setVersion(version);
// 声明为泛化接口
referenceConfig.setGeneric(true);
return cache.get(referenceConfig);
}
/**
* 创建ReferenceConfig 对象
*
* @param applicationName 应用名
* @param address 地址
* @param protocol 协议
* @param check 是否检测提供者
* @param timeout 超时时间
* @return
*/
private ReferenceConfig<GenericService> createReferenceConfig(String applicationName, String address, String protocol, Boolean check, Integer timeout) {
ReferenceConfig<GenericService> referenceConfig = new ReferenceConfig<GenericService>();
ApplicationConfig application = new ApplicationConfig();
application.setName(applicationName);
referenceConfig.setApplication(application);
RegistryConfig registryConfig = new RegistryConfig(address);
registryConfig.setProtocol(protocol);
ConsumerConfig consumerConfig = new ConsumerConfig();
consumerConfig.setCheck(check);
consumerConfig.setTimeout(timeout);
referenceConfig.setRegistry(registryConfig);
referenceConfig.setConsumer(consumerConfig);
return referenceConfig;
}
2:动态调用
public class DynamDubboImpl implements IDynamDubbo {
private static final String VARCHAR = "java.lang.String";
@Autowired
private MyReferenceUtils myReferenceUtils;
@SuppressWarnings("unchecked")
@Override
public Object invoke(String clazzName, String method, String version, String parameter) {
GenericService genericService = myReferenceUtils.getCacheGenericServiceByKey(clazzName, version);
return genericService.$invoke(method, new String[]{VARCHAR}, new Object[]{parameter});
}
@Override
public Object invoke(String clazzName, String method, String version, Map<String, String> parameter) {
List<String> types = new ArrayList<String>();
List<Object> values = new ArrayList<>();
parameter.forEach((key, value) -> {
if(String.class.getName().equals(key)){
types.add(key);
values.add(value.toString());
}else {
types.add(key);
JSONObject jsonObject = JSONObject.parseObject(value);
Map<String, Object> map = (Map<String, Object>) jsonObject;
values.add(map);
}
});
GenericService genericService = myReferenceUtils.getCacheGenericServiceByKey(clazzName, version);
String[] dtypes = types.toArray(new String[types.size()]);
Object result = genericService.$invoke(method, dtypes, values.toArray());
try {
String resultJsonStr = JSONObject.toJSONString(result, WriteNullStringAsEmpty);
resultJsonStr = resultJsonStr.replaceAll("[,]*\"class\":\"(.+?)\"", "");
result = JSONObject.parse(resultJsonStr);
} catch (JSONException ignored) {
}
return result;
}
@Override
public Object invoke(String clazzName, String method, String version, String[] parameters) {
GenericService genericService = myReferenceUtils.getCacheGenericServiceByKey(clazzName, version);
List<String> types = new ArrayList<String>();
if (parameters != null && parameters.length > 0) {
int count = parameters.length;
for (int i = 0; i < count; i++) {
types.add(VARCHAR);
}
return genericService.$invoke(method, (String[]) types.toArray(), parameters);
}
return null;
}