外观
外观
574字约2分钟
2024-05-18
RPC 框架的核心功能是调用其他远程服务。但是在实际开发和测试过程中,有时可能无法直接访问真实的远程服务,或者访问真实的远程服务可能会产生不可控的影响,例如网络延迟、服务不稳定等。在这种情况下,就可以使用 mock 服务来模拟远程服务的行为,以便进行接口的测试、开发和调试。
虽然 mock 服务并不是 RPC 框架的核心能力,但是它的开发成本并不高。而且给 RPC 框架支持 mock后,开发者就可以轻松调用服务接口、跑通业务流程,不必依赖真实的远程服务,提高使用体验。
通过动态代理创建一个调用方法时返回固定值的对象。
1、 首先支持开发者通过修改配置文件的方式开启 mock,那么首先给全局配置类 rpcconfig新增 mock字段,默认值为 false。
/**
* 模拟调用
*/
private boolean mock = false;
2、在 proxy 包下创建 MockServiceProxy 类,用于实现生成 mock 代理服务。在该类中提供一个根据服务接口类型返回固定值的方法。
@Slf4j
public class MockServiceProxy implements InvocationHandler {
/**
* 调用代理
* @param proxy
* @param method
* @param args
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Class<?> methodReturnType = method.getReturnType();
log.info("mock invoke {}",method.getName());
return getDefaultObject(methodReturnType);
}
/**
*
* @param type
* @return
*/
private Object getDefaultObject(Class<?> type){
//基本类型
if(type.isPrimitive()){
if(type == boolean.class){
return false;
} else if (type == short.class) {
return (short) 0;
} else if (type == int.class) {
return 0;
} else if (type == long.class) {
return 0L;
}
}
//对象类型
return null;
}
}
3、给 ServiceProxyFactory 服务代理工厂新增获取 mock 代理对象的方法 getMockProxy 。通过读取已定义的全局配置 mock 来区分创建哪种代理对象。
public class ServiceProxyFactory {
/**
* 根据服务类获取代理对象
* @param serviceClass
* @return
* @param <T>
*/
public static <T> T getProxy(Class<T> serviceClass){
if(RpcApplication.getRpcConfig().isMock()){
return getMockProxy(serviceClass);
}
return (T) Proxy.newProxyInstance(
serviceClass.getClassLoader(),
new Class[]{serviceClass},
new ServiceProxy()
);
}
/**
* 根据服务类获取 Mock 对象
* @param serviceClass
* @return
* @param <T>
*/
private static <T> T getMockProxy(Class<T> serviceClass) {
return (T) Proxy.newProxyInstance(
serviceClass.getClassLoader(),
new Class[]{serviceClass},
new MockServiceProxy()
);
}
}