dubbo泛化调用 http接口 随意调用dubbo服务
2017-10-27 10:31
337 查看
dubbo支持泛化调用
1、开发工程中 有时候想要测试dubbo接口 需要自定义用例,比较麻烦
2、无法调用服务器上的dubbo测试
3、无法随意调用多版本的服务
由于dubbo支持泛化调用 所以这些问题就迎刃而解了
具体源码可以参考
https://gitee.com/li35619081/dubbo-test
1、开发工程中 有时候想要测试dubbo接口 需要自定义用例,比较麻烦
2、无法调用服务器上的dubbo测试
3、无法随意调用多版本的服务
由于dubbo支持泛化调用 所以这些问题就迎刃而解了
/* * Copyright 1999-2011 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.alibaba.dubbo.rpc.service; /** * 通用服务接口 * * @author william.liangf * @export */ public interface GenericService { /** * 泛化调用 * * @param method 方法名,如:findPerson,如果有重载方法,需带上参数列表,如:findPerson(java.lang.String) * @param parameterTypes 参数类型 * @param args 参数列表 * @return 返回值 * @throws Throwable 方法抛出的异常 */ Object $invoke(String method, String[] parameterTypes, Object[] args) throws GenericException; }
package com.test.consumer; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import com.alibaba.dubbo.common.Constants; import com.alibaba.dubbo.common.bytecode.Wrapper; import com.alibaba.dubbo.rpc.service.GenericService; import javassist.ClassPool; import javassist.CtClass; import javassist.CtMethod; import javassist.NotFoundException; import javassist.bytecode.CodeAttribute; import javassist.bytecode.LocalVariableAttribute; import javassist.bytecode.MethodInfo; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.zookeeper.ClientCnxn; import com.alibaba.dubbo.common.utils.StringUtils; import com.alibaba.dubbo.config.ApplicationConfig; import com.alibaba.dubbo.config.ReferenceConfig; import com.alibaba.dubbo.config.RegistryConfig; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Configuration; import org.springframework.util.CollectionUtils; import org.springframework.util.ReflectionUtils; import static java.lang.Class.forName; /** * Created by on 2017/10/23. */ public class DubboCallbackUtil { private static Logger logger = LogManager.getLogger(DubboCallbackUtil.class); // 当前应用的信息 private static ApplicationConfig application = new ApplicationConfig(); // 注册中心信息缓存 private static Map<String, RegistryConfig> registryConfigCache = new ConcurrentHashMap<>(); // 各个业务方的ReferenceConfig缓存 private static Map<String, ReferenceConfig> referenceCache = new ConcurrentHashMap<>(); static { application.setName("consumer-test"); } /** * 获取注册中心信息 * * @param address zk注册地址 * @param group dubbo服务所在的组 * @return */ private static RegistryConfig getRegistryConfig(String address, String group, String version) { String key = address + "-" + group + "-" + version; RegistryConfig registryConfig = registryConfigCache.get(key); if (null == registryConfig) { registryConfig = new RegistryConfig(); if (StringUtils.isNotEmpty(address)) { registryConfig.setAddress(address); } if (StringUtils.isNotEmpty(version)) { registryConfig.setVersion(version); } if (StringUtils.isNotEmpty(group)) { registryConfig.setGroup(group); } registryConfigCache.put(key, registryConfig); } return registryConfig; } private static ReferenceConfig getReferenceConfig(String interfaceName, String address, String group, String version) { String referenceKey = interfaceName; ReferenceConfig referenceConfig = referenceCache.get(referenceKey); if (null == referenceConfig) { try { referenceConfig = new ReferenceConfig<>(); referenceConfig.setApplication(application); referenceConfig.setRegistry(getRegistryConfig(address, group, version)); Class interfaceClass = forName(interfaceName); referenceConfig.setInterface(interfaceClass); if (StringUtils.isNotEmpty(version)) { referenceConfig.setVersion(version); } referenceConfig.setGeneric(true); //referenceConfig.setUrl("dubbo://10.1.50.167:20880/com.test.service.HelloService"); referenceCache.put(referenceKey, referenceConfig); } catch (ClassNotFoundException e) { e.printStackTrace(); } } return referenceConfig; } public static Object invoke(String interfaceName, String methodName, List<Object> paramList, String address, String version) { ReferenceConfig reference = getReferenceConfig(interfaceName, address, null, version); if (null != reference) { GenericService genericService = (GenericService) reference.get(); if (genericService == null) { logger.debug("GenericService 不存在:{}", interfaceName); return null; } Object[] paramObject = null; if (!CollectionUtils.isEmpty(paramList)) { paramObject = new Object[paramList.size()]; for (int i = 0; i < paramList.size(); i++) { paramObject[i] = paramList.get(i); } } Object resultParam = genericService.$invoke(methodName, getMethodParamType(interfaceName, methodName), paramObject); return resultParam; } return null; } public static String[] getMethodParamType(String interfaceName, String methodName) { try { //创建类 Class<?> class1 = Class.forName(interfaceName); //获取所有的公共的方法 Method[] methods = class1.getMethods(); for (Method method : methods) { if (method.getName().equals(methodName)) { Class[] paramClassList = method.getParameterTypes(); String[] paramTypeList = new String[paramClassList.length]; int i = 0; for (Class className : paramClassList) { paramTypeList[i] = className.getTypeName(); i++; } return paramTypeList; } } } catch (Exception e) { e.printStackTrace(); } return null; } }
package com.test.consumer.controller; import com.test.consumer.DubboCallbackUtil; import com.test.consumer.dto.request.CallRequest; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import java.util.Map; /** * Created by on 2017/10/20. */ @RestController @RequestMapping(value = "/consumer") public class ConsumerController { @RequestMapping(value = "/callJson") @ResponseBody public Object call(@RequestBody CallRequest request) { return DubboCallbackUtil.invoke(request.getInterfaceName(), request.getMethod(), request.getParam(), request.getAddress(), request.getVersion()); } }
具体源码可以参考
https://gitee.com/li35619081/dubbo-test
相关文章推荐
- dubbo组成原理-http服务消费端如何调用
- 使用接口的方式调用远程服务 ------ 利用动态调用服务,实现.net下类似Dubbo的玩法。
- springboot 集成dubbo,RPC 远程调用服务接口:提示服务空指针异常
- 既然有http 请求,为什么还要用rpc(dubbo接口)调用?
- dubbo泛化 不使用接口jar包调用接口
- 通过dubbo+zookeeper实现服务接口的封装及调用
- Dubbo剖析-服务消费端泛化调用
- dubbo+zookeeper实现服务远程调用
- dubbo服务划分和接口设计原则(五)
- 使用Spring Cloud Feign作为HTTP客户端调用远程HTTP服务
- apache httpclient HTTPS发送JSON调用接口实例
- SpringCloud(第 012 篇)电影微服务接入 Feign 进行客户端负载均衡,通过 FeignClient 调用远程 Http 微服务
- C#调用HTTP接口
- (推荐)Skyline调用WMTS服务接口
- curl库调用http接口方法
- Python调用服务接口
- Android(java)学习笔记229:服务(service)之绑定服务调用服务里面的方法 (采用接口隐藏代码内部实现)
- 通过dubbo暴露接口调用方法,及基于zookeeper的dubbo涉及配置文件【转】
- php通过http调用验证码短信接口源码
- http接口的调用于被调用的简单实现