前言
大家好,今天开始给大家分享 — Dubbo 专题之 Dubbo Stub
和Mock
。在前一个章节中我们介绍了 Dubbo 事件通知,以及我们也例举了常见的使用场景并且进行了源码解析来分析其实现原理,同时知道 Dubbo 中的事件通知可以在某个服务调用之前、调用之后、异常发生时触发回调事件,我们可以通过回调事件做一些额外的工作。我们在 Dubbo 服务开发过程中可能遇到我们调用的服务方并没有编写完成,那我们是不是需要等待服务提供方开发完成我们才能开始测试呢?那么在本章节我们会通过介绍 Dubbo Stub
和 Mock
来解决这个问题。那么什么是 Stub
和 Mock
?下面就让我们快速开始吧!
1. 本地 Stub/Mock 简介
在 Dubbo 中提供的 Stub
也可称为本地存根具有类似代理模式的功能,即把我们调用的真正对象重新包装然后把包装对象提供给调用方,那么在调用真正的对象之前和之后我们可以做相应处理逻辑。同理 Mock
也可称为本地伪装和本地存根具有类似原理只是 Mock
针对发生RpcException
异常或者我们强制使用 Mock
方式才去调用 Mock
的实现。从下面我们可以看出来Stub
和 Mock
与代理对象关系:
从图中我们可以看出的 Stub
和 Mock
都是实现同一个服务的接口,它们都是通过代理对象来调用远程暴露的服务,而 Mock
紧紧是在调用失败时会触发。
Tips:
Mock
是Stub
的一个子集,便于服务提供方在客户端执行容错逻辑,因经常需要在出现RpcException
(比如网络失败,超时等)时进行容错,而在出现业务异常(比如登录用户名密码错误)时不需要容错,如果用Stub
,可能就需要捕获并依赖RpcException
类,而用Mock
就可以不依赖RpcException
,因为它的约定就是只有出现RpcException
时才执行。
2. 使用方式
2.1 Stub
配置方式
<dubbo:service interface="com.foo.BarService" stub="true" />
或者
<dubbo:service interface="com.foo.BarService" stub="com.foo.BarServiceStub" />
Stub
的实现类:
/**
* @author <a href="http://youngitman.tech">青年IT男</a>
* @version v1.0.0
* @className BookFacadeStub
* @description
* @JunitTest: {@link }
* @date 2020-11-15 23:43
**/
public class BookFacadeStub implements BookFacade {
//真正远程服务对象
private BookFacade bookFacade;
//必须提供BookFacade签名的构造函数
public BookFacadeStub(BookFacade bookFacade){
this.bookFacade = bookFacade;
}
@Override
public List<Book> queryAll() {
try {
//做一些前置处理
return bookFacade.queryAll();
} catch (Exception e) {
// 发生异常做一些处理
return Lists.newArrayList();
}finally {
//做一些后置处理
}
}
}
2.2 Mock
配置方式
<dubbo:reference interface="com.foo.BarService" mock="true" />
或者
<dubbo:reference interface="com.foo.BarService" mock="com.foo.BarServiceMock" />
Mock
的实现类:
public class BookFacadeMock implements BookFacade {
/**
*
* 这里我们可以把服务端的方法执行时间加大 使之超时就可以触发Mock的调用
*
* @author liyong
* @date 12:18 AM 2020/11/16
* @param
* @exception
* @return List<Book>
**/
@Override
public List<Book> queryAll() {
// 你可以伪造容错数据,此方法只在出现RpcException时被执行
Book book = new Book();
book.setDesc("default");
book.setName("default");
return Lists.newArrayList(book);
}