需求::抽取一段公共代码,作用是给三个属性赋值,但是传入的参数类型不确定
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远程调用超时,很奇怪的就是后台并没有报错,只是前端返回了操作失败,一步步跟踪代码才找到这个调用超时的错误