您的位置:首页 > 理论基础 > 计算机网络

dubbo泛化调用 http接口 随意调用dubbo服务

2017-10-27 10:31 337 查看
dubbo支持泛化调用

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