【DUBBO】在不使用Spring的情况下调用Dubbo服务

在不使用Spring的情况下调用Dubbo服务

背景

    当我们开发工具类时、需要调用dubbo服务的情况下、往往不希望添加dubbo的xml配置文件。
否则开发好的工具栏调用太不友好。

解决方案

方案一:静态调用

调用示例(方案一)

@Test
public void testDubboNoGenericService(){
    UserService userService = DubboUtils.getService(
            UserService.class, "1.0.0");
    UserDto userDto = userService.getUserByIdentify("admin");
    System.out.println(userDto.getRealname());
}

调用示例(方案二)

@Test
public void testDubboGenericService(){
    Object result = DubboUtils.callGenericService(
            "com.tyyd.xroic.api.service.UserService", 
            "getUserByIdentify", "1.0.0",
            new String[]{"java.lang.String"}, 
            new Object[]{"admin"});
    System.out.println(result);
}

实现代码

package com.acws.ext.dubbo;

import com.acws.core.AcwsInfo;
import com.acws.core.util.StringUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ConsumerConfig;
import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.rpc.service.GenericService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class DubboUtils {
    private static final Logger logger = LoggerFactory.getLogger(DubboUtils.class);
    public static final Map<String, Object> serviceMap = new HashMap<>();

    /**
     * 取得Dubbo bean
     * @param clazz
     * @param version
     * @param tag 可以不传 不传的话取system环境变量
     * @param <T>
     * @return
     */
    public static <T>  T getService(Class<T> clazz, String version, String... tag) {
        if(clazz == null || StringUtils.isBlank(version)) {
            throw new IllegalArgumentException("DubboUtils#getService():参数不能为空.");
        }
        String key = StringUtil.addString(clazz.getName(), ":", version);
        Object objService = serviceMap.get(key);
        if(objService!= null && !StringUtils.equals(objService.getClass().getName(), clazz.getName())) {
            throw new IllegalArgumentException("DubboUtils#getService():返回值类型不符.期望:"+clazz.getName()+
                    ",实际:"+objService.getClass().getName());
        }
        if(serviceMap.containsKey(key)) {
            return (T) objService;
        }

        ReferenceConfig reference = createReferenceConfig();

        // 设置tag:用于灰度发布、线上程序调试
        String tagEnv = getTag(tag);
        if (StringUtils.isNotBlank(tagEnv)) {
            ConsumerConfig consumerConfig = new ConsumerConfig();
            consumerConfig.setTag(tagEnv);
            reference.setConsumer(consumerConfig);
        }

        reference.setVersion(version);
        // 弱类型接口名
        reference.setInterface(clazz);
        // 声明为泛化接口
        reference.setGeneric("fasle");

        objService = reference.get();
        serviceMap.put(key, objService);
        return (T)objService;
    }

    /**
     * 取得Dubbo Bean
     * @param clazz
     * @param methodName
     * @param version
     * @param paramsClassName
     * @param params
     * @param tag 可以不传 不传的话取system环境变量
     * @return
     */
    public static Object callGenericService(String clazz, String methodName, String version, String[] paramsClassName, Object[] params, String... tag) {
        if(StringUtils.isBlank(clazz) || StringUtils.isBlank(methodName)) {
            throw new IllegalArgumentException("DubboUtils#callGenericService():参数不能为空.packageName="+clazz+",methodName="+methodName);
        }
        if((paramsClassName!=null && params == null) || (paramsClassName==null && params!= null)) {
            throw new IllegalArgumentException("DubboUtils#callGenericService():参数设置错误.paramsClassName="+clazz+",params="+params);
        }
        if((paramsClassName != null && params != null) && (paramsClassName.length != params.length)) {
            throw new IllegalArgumentException("DubboUtils#callGenericService():参数设置错误.paramsClassName="+clazz+",params="+params);
        }
        String key = StringUtil.addString(clazz, ".", methodName, ":", version, ":gen");
        Object objService = serviceMap.get(key);
        if(objService!=null && !(objService instanceof  GenericService)) {
            throw new IllegalArgumentException("DubboUtils#callGenericService():返回值类型不符.期望:GenericService,实际:"+objService.getClass().getName());
        }
        if(serviceMap.containsKey(key) && objService == null) {
            throw new IllegalArgumentException("DubboUtils#callGenericService():获取远程bean失败.");
        }

        if(objService == null) {
            ReferenceConfig reference = createReferenceConfig();

            // 设置tag:用于灰度发布、线上程序调试
            String tagEnv = getTag(tag);
            if (StringUtils.isNotBlank(tagEnv)) {
                ConsumerConfig consumerConfig = new ConsumerConfig();
                consumerConfig.setTag(tagEnv);
                reference.setConsumer(consumerConfig);
            }
            reference.setVersion(version);
            // 弱类型接口名
            reference.setInterface(clazz);
            // 声明为泛化接口
            reference.setGeneric("true");

            objService = reference.get();
            serviceMap.put(key, objService);
        }

        // 基本类型以及Date,List,Map等不需要转换,直接调用
        GenericService genericService = (GenericService) objService;
        return genericService.$invoke(methodName, paramsClassName, params);
    }

    private static ReferenceConfig createReferenceConfig() {
        // 普通编码配置方式
        ApplicationConfig application = new ApplicationConfig();
        // 客户端应用名:可以任意取名
        application.setName("acws-dubbo-generic-" + AcwsInfo.getAcwsAppShortName());
        application.setLogger("slf4j");

        // 连接注册中心配置
        RegistryConfig registry1 = new RegistryConfig();
        registry1.setAddress("zookeeper://vr-zk-1.189read.com:2181");
        RegistryConfig registry2 = new RegistryConfig();
        registry2.setAddress("zookeeper://vr-zk-2.189read.com:2181");
        List<RegistryConfig> registries = new ArrayList<>();
        registries.add(registry1);
        registries.add(registry2);

        // 引用远程服务
        // 该实例很重量,里面封装了所有与注册中心及服务提供方连接,请缓存
        ReferenceConfig reference = new ReferenceConfig();
        reference.setApplication(application);
        reference.setRegistries(registries);
        reference.setCheck(false);
        return reference;
    }

    private static String getTag(String... tag) {
        String tagEnv = System.getProperty("dubbo.provider.tag");
        if (tag != null && tag.length > 0 && StringUtils.isNotBlank(tag[0])) {
            tagEnv = tag[0];
        }
        return tagEnv;
    }
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Cloud Alibaba中使用Dubbo进行分布式服务需要进行以下步骤: 1. 添加Dubbo依赖:在pom.xml文件中添加Dubbo依赖,例如: ``` <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-dubbo</artifactId> <version>2.2.3.RELEASE</version> </dependency> ``` 2. 配置Dubbo:在application.properties或者application.yml文件中添加Dubbo配置,例如: ``` #Dubbo配置 spring: dubbo: application: name: dubbo-provider #服务提供者名称 registry: address: nacos://localhost:8848 #注册中心地址 protocol: name: dubbo #协议名称 port: 20880 #协议端口号 ``` 3. 编写Dubbo服务接口:在服务提供者中定义Dubbo服务接口,例如: ``` public interface UserService { User getUserById(Long id); } ``` 4. 实现Dubbo服务接口:在服务提供者中实现Dubbo服务接口,例如: ``` @Service(version = "1.0.0") public class UserServiceImpl implements UserService { @Override public User getUserById(Long id) { //实现方法 } } ``` 5. 注册Dubbo服务:在服务提供者中使用@DubboService注解注册Dubbo服务,例如: ``` @Service(version = "1.0.0") @DubboService(interfaceClass = UserService.class) public class UserServiceImpl implements UserService { @Override public User getUserById(Long id) { //实现方法 } } ``` 6. 调用Dubbo服务:在服务消费者中使用@DubboReference注解调用Dubbo服务,例如: ``` @Service public class UserServiceImpl implements UserService { @DubboReference(version = "1.0.0") private UserService userService; public User getUserById(Long id) { return userService.getUserById(id); } } ``` 以上就是在Spring Cloud Alibaba中使用Dubbo进行分布式服务的步骤。需要注意的是,Dubbo还支持其他的注册中心和负载均衡策略,可以根据实际情况进行配置。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值