我们的系统采用是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; }