5.2 本地服务mock原理
5.2.1 mock合法性检查
在3.3节我们讲解了在服务引用启动时会在ReferenceConfig的init()方法内调用checkMock来检查设置的mock的正确性,下面我们看看相应的代码:
如果代码1没有设置mock规则,则直接返回,否则代码2对mock规则进行格式化:
例如,如果设置mock为return,则格式化后为return null。
代码将检查mock值是否合法,不合法将抛出异常。由于我们的Demo是将mock设置为true,所以我们会看到代码4将检查mock接口的实现类是否符合规则,MockInvoker.getMockObject的代码如下:
如果代码5中的mock类型为true或者deafult,则mockService被设置为接口名称加上Mock,例如,如果接口为com.books.dubbo.demo.api.GreetingServic并且mock设置为true,则这里的mockService就是com.books.dubbo.demo.api.GreetingServicMock,然后代码6加载com.books.dubbo.demo.api.GreetingServicMock的字节码文件以创建Class对象,代码7则创建实例。上面这些代码的作用是查看用户程序的classpath下是否存在mock类的实现com.books.dubbo.demo.api.GreetingServicMock,如果不存在,则抛出异常。
5.2.2 服务消费端使用mock服务
mock服务与服务降级策略一样,也是在MockClusterInvoker中实现的,这里我们再看看其中的invoke()方法:
由于我们设置的mock为true,所以这里的value为true,代码会执行到步骤3也就是fail-mock阶段,这也说明了服务mock与服务降级的fail-mock功能相似,不同之处在于前者会设置mock服务实现类,而后者是返回设置的静态返回值。代码3会首先发起远程RPC,如果成功则不会执行mock操作,否则执行doMockInvoke。
MockInvoker的invoke()方法如下:
通过上面的代码可知,根据mock类型的不同,返回不同的mock值。这里我们重点看看代码7,即mock实现类GreetingServiceMock如何返回mock值:
通过上面的代码可知,如果缓存里含有mock实现类对应的invoker对象,则直接返回,否则使用getMockObject()方法创建对象实例,并进行代理后保存到缓存,然后返回。在调用代理的invoke()方法后,就会调用mock实现类GreetingServiceMock的方法。