dubbo 本地存根
官网:https://dubbo.apache.org/zh/docs/advanced/local-stub/
本地存根
应用:消费端做threadlocal缓存、参数验证、调用失败伪造容错数据等
服务调用接口
public interface BarService {
public String sayHello(String name);
}
消费端:stub实现类
public class BarServiceStub implements BarService {
private final BarService barService;
public BarServiceStub(BarService barService){
this.barService = barService;
} //构造函数传入真正的远程代理对象(必须有该构造方法)
public String sayHello(String name) {
try {
return barService.sayHello(name);
} catch (Exception e) {
return "容错数据"; //返回容错数据
} //也可在客户端做ThreadLocal本地缓存、验证参数是否合法等
}
}
消费端调用
# 在同目录查找stub类
<dubbo:reference interface="com.foo.BarService" stub="true" />
# 指定stub的全路径名
<dubbo:reference interface="com.foo.BarService" stub="com.foo.BarServiceStub" />
AbstractInterfaceConfig:stub为true时,默认的stub类存储位置
public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
/**
* Legitimacy check of stub, note that: the local will deprecated, and replace with <code>stub</code>
*
* @param interfaceClass for provider side, it is the {@link Class} of the service that will be exported; for consumer
* side, it is the {@link Class} of the remote service interface
*/
protected void checkStubAndLocal(Class<?> interfaceClass) {
verifyStubAndLocal(local, "Local", interfaceClass);
verifyStubAndLocal(stub, "Stub", interfaceClass);
}
private void verifyStubAndLocal(String className, String label, Class<?> interfaceClass){
if (ConfigUtils.isNotEmpty(className)) {
Class<?> localClass = ConfigUtils.isDefault(className) ?
ReflectUtils.forName(interfaceClass.getName() + label) : ReflectUtils.forName(className);
verify(interfaceClass, localClass);
}
}
使用示例
**********
服务端
application.yml
dubbo:
application:
name: dubbo-provider
#register-mode: instance
registry:
address: localhost:2181
protocol: zookeeper
group: dubbo
protocol:
name: dubbo
#port: 20880
HelloService
public interface HelloService {
String hello();
}
HelloServiceImpl
@DubboService
public class HelloServiceImpl implements HelloService {
@Override
public String hello() {
return "hello";
}
}
**********
消费端
application.yml
dubbo:
application:
name: dubbo-consumer
registry:
protocol: zookeeper
address: localhost:2181
group: dubbo
#register-mode: instance
protocol:
name: dubbo
#port: 20880
server:
port: 8081
HelloService
public interface HelloService {
String hello();
}
HelloServiceStub
public class HelloServiceStub implements HelloService {
private HelloService helloService;
public HelloServiceStub(HelloService helloService){
this.helloService=helloService;
}
@Override
public String hello() {
try {
System.out.println("消费端stub方法");
return helloService.hello();
}catch (Exception e){
return "failure";
}
}
}
HelloController
@RestController
public class HelloController {
@DubboReference(stub = "com.example.demo.service.stub.HelloServiceStub")
private HelloService helloService;
@RequestMapping("/hello")
public String hello(){
return helloService.hello();
}
}
**********
使用测试
localhost:8081/hello,控制台输出:
2022-02-24 18:03:31.883 INFO 4887 --- [ main] com.example.demo.DemoApplication : Started DemoApplication in 3.098 seconds (JVM running for 3.555)
2022-02-24 18:03:33.562 INFO 4887 --- [nio-8081-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2022-02-24 18:03:33.562 INFO 4887 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2022-02-24 18:03:33.563 INFO 4887 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 1 ms
消费端stub方法
消费端执行了HelloServiceStub方法