zookeeper+dubbo架构: 远程调用反射实现的方法(alibaba dubbo底层调用invoke报错:dubbo超时 )

需求::抽取一段公共代码,作用是给三个属性赋值,但是传入的参数类型不确定

facade:提供外部调用

provider:facade的实现类

helper:抽取的方法(作用类似于Service)

项目架构:zookeeper+dubbo为主体实现远程调用的微服务架构

Facade:


public interface UserInfoSetHelperFacade {

    <T> T fillReqWithInfo(T t, String loginId);
}

Provider:

import com.alibaba.dubbo.config.annotation.Service;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
@Service(version = "1.0.0")
public class UserInfoSetHelperProvider implements UserInfoSetHelperFacade {

    @Autowired
    private UserInfoSetHelper userInfoSetHelper;

    @SneakyThrows
    @Override
    public <T> T fillReqWithInfo(T t, String loginId) {
        return userInfoSetHelper.fillReqWithInfo(t, loginId);
    }
}

helper:

package com.ipig.third.helper;


import com.alibaba.dubbo.config.annotation.Reference;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.lang.reflect.Method;

@Service
@Component
public class UserInfoSetHelper {

    @Reference(version = "1.0.0")
    private AccountFacade accountFacade;

    public <T> T fillReqWithInfo(T t, String loginId) throws Exception {
        Class<T> clazz = (Class<T>) t.getClass();
        try {
            AccountResp.LoginInfoResp info = accountFacade.merchantLoginInfo(loginId);

            // 获取req中的构造方法对应的Constructor对象
            Method host = clazz.getDeclaredMethod("setHostAddress", String.class);
            Method suser = clazz.getDeclaredMethod("setSuperUser", String.class);
            Method spwd = clazz.getDeclaredMethod("setSuperUserPassword", String.class);

            host.invoke(t, info.getHostAddress());
            suser.invoke(t, info.getSuperUser());
            spwd.invoke(t, info.getSuperUserPassword());
        } catch (Exception e) {
            e.printStackTrace();
        }

        return t;
    }
}

下面是调用的Controller中的部分:

Controller与上面的文件不同属一个微服务

 @SneakyThrows
    @GetMapping(path = "/confined/kf/getDataAnimalList")
    public ResponseListModel getDataAnimalList(TKfDataAnimalReq.queryReq req) {
        String key = RedisKeyConstant.KF_ANIMAL_LIST + (req.getSearchParams() != null ? MD5Helper.encrypt32(req.getSearchParams()) : "");
        String cacheStr = (String) redisCachemanager.get(key);
        ResponseModel test;
        String loginId = (String) ThreadLocalContextUtil.getValue(SystemConstant.SHOUYI_WEB_COOKIE_LOGIN_ID_NAME);
        // 在req里填充hostAddress, superUser, superUserPassword
        try {
            req = userInfoSetHelperFacade.fillReqWithInfo(req, loginId);
        } catch (Exception e) {
            e.printStackTrace();
        }

        if (StringUtils.isBlank(cacheStr)) {
            test = tKfDataAnimalFacade.getDataAnimalList(req);
            Boolean flag = "000".equals(test.getCode());
            if (flag) {
                redisCachemanager.set(key, JSON.toJSONString(test), 30 * 60);
            }
        } else {
            test = JSON.parseObject(cacheStr, ResponseModel.class);
        }
        return ResponseModel.wrapToResponseListModel(test);
    }

这里主要是根据controller传入的req的类型来对req里面的三个属性进行赋值(req可以理解为一个实体类,主要是用来接受页面传入的参数的),我们这里传入的参数是req,方法返回的类型也是req,但是这里要注意,这两个req并不是同一个对象,而是两个完全不同的对象,即同类型不同对象,如果不把返回的req里面的属性赋值给方法接收到的req,那么传入下面(test = tKfDataAnimalFacade.getDataAnimalList(req);)的req里面的属性就是原始的未赋值的,所以我在这里报错了:

这里报错是dubbo远程调用超时,很奇怪的就是后台并没有报错,只是前端返回了操作失败,一步步跟踪代码才找到这个调用超时的错误

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值