你们好,今天开始给你们分享 — Dubbo 专题之 Dubbo 泛化引用。在前一个章节中咱们介绍了 Dubbo 中的参数验证以及使用场景。咱们在这个章节会继续介绍 Dubbo 泛化引用。那么什么是泛化引用呢?泛化引用有什么做用呢?下面就让我详细了解下吧!java
在前面的章节中咱们编写的 Dubbo 服务都是基于 API 接口,例如:com.muke.dubbocourse.common.api.BookFacade
接口。咱们在平常开发中的步骤都是首先定义好暴露服务的 API 接口,而后把这个接口打包成 jar 提供给服务调用方。也就是说一般状况下咱们的服务调用方都会依赖咱们定义的 API 接口编程。那么在 Dubbo 中为咱们提供一种不须要依赖 API 接口的方式进行服务调用,这种方式就泛化引用。其表示类为GenericService
。git
在这里咱们主要介绍两种使用方式:spring
配置 XML 文件中的服务引用为generic="true"
apache
<dubbo:reference id="barService" interface="com.muke.dubbocourse.common.api.BookFacade" generic="true" />
在代码中使用泛化调用编程
GenericService barService = (GenericService) applicationContext.getBean("bookFacade"); Object result = barService.$invoke("queryAll", null, null);
// 引用远程服务 ReferenceConfig<GenericService> reference = new ReferenceConfig<GenericService>(); // 弱类型接口名 reference.setInterface("com.muke.dubbocourse.common.api.BookFacade"); reference.setVersion("0.0.1"); // 声明为泛化接口 reference.setGeneric(true); // 用org.apache.dubbo.rpc.service.GenericService能够替代全部接口引用 GenericService genericService = reference.get(); // 若是返回实体对象将自动转成Map Object result = genericService.$invoke("queryByName",new String[] {"com.muke.dubbocourse.common.api.RequestParameter"}, new Object[]{parameter});
从泛化引用自己咱们能够知道它是不须要 API 接口,也就是说泛化引用使用场景在服务提供方没有明确的 API 接口提供的状况下咱们均可以使用。一般用于框架集成,好比:实现一个 Dubbo 服务对外统一网,就可经过 GenericService
调用后端全部服务实现。 例如:后端
在上面的图中客户端经过统一的Dubbo网关访问后端全部的 Dubbo 服务,这里就是使用 泛化调用实现。api
下面咱们经过两种方式来演示一个获取图书列表的服务。数组
主要看消费端 XML 配置文件dubbo-consumer-xml.xml
微信
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://dubbo.apache.org/schema/dubbo" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd"> <dubbo:application name="demo-consumer" logger="log4j"/> <!--使用zookeeper注册中心--> <dubbo:registry address="zookeeper://127.0.0.1:2181" /> <!--设置generic="true"--> <dubbo:reference id="bookFacade" interface="com.muke.dubbocourse.common.api.BookFacade" generic="true"></dubbo:reference> </beans>
消费端 Java 代码app
public class XmlApplication { public static void main(String[] args) throws IOException { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("generic/consumer/spring/dubbo-consumer-xml.xml"); context.start(); //建立泛化调用对象 GenericService bookFacade = (GenericService) context.getBean("bookFacade"); RequestParameter parameter = new RequestParameter(); parameter.setName("SpringBoot"); //泛化调用 第一个参数:方法名称,第二个参数:请求参数类型的数组,第三方个参数:请求参数值的数组 Object result = bookFacade.$invoke("queryByName", new String[] { "com.muke.dubbocourse.common.api.RequestParameter" }, new Object[] { parameter }); System.out.println("Result=>"+result); System.in.read(); } }
public class XmlApplication2 { public static void main(String[] args) throws IOException { // 引用远程服务 ReferenceConfig<GenericService> reference = new ReferenceConfig<>(); // 弱类型接口名 reference.setInterface("com.muke.dubbocourse.common.api.BookFacade"); //注册中心配置 RegistryConfig registryConfig = new RegistryConfig(); registryConfig.setAddress("zookeeper://127.0.0.1:2181"); reference.setRegistry(registryConfig); //应用配置 ApplicationConfig applicationConfig = new ApplicationConfig(); applicationConfig.setName("demo-consumer"); reference.setApplication(applicationConfig); // 声明为泛化接口 reference.setGeneric(true); // 用org.apache.dubbo.rpc.service.GenericService能够替代全部接口引用 GenericService genericService = reference.get(); RequestParameter parameter = new RequestParameter(); parameter.setName("SpringBoot"); Object result = genericService.$invoke("queryByName", new String[]{"com.muke.dubbocourse.common.api.RequestParameter"}, new Object[]{parameter}); System.out.println("Result=>" + result); System.in.read(); } }
在上面的代码中咱们经过 Java API的方式配置了注册中心、应用配置。在调用服务的使用和上面的Spring使用方式相似使用org.apache.dubbo.rpc.service.GenericService#$invoke
方法。
在上面的代码GenericService genericService = reference.get()
中会调用到org.apache.dubbo.config.ReferenceConfig#init
方法,而在此方法中org.apache.dubbo.config.ReferenceConfig#createProxy
方法建立一个服务调用代理对象。当咱们调用genericService.$invoke
方法是实际调用的是org.apache.dubbo.rpc.proxy.InvokerInvocationHandler#invoke
方法而后调用org.apache.dubbo.rpc.cluster.support.wrapper.MockClusterInvoker#invoke
调用咱们org.apache.dubbo.rpc.cluster.support.AbstractClusterInvoker#invoke
在此方法中就查找咱们的调用远程的 Invoker 对象,时序图以下:
在本小节中咱们主要学习了 Dubbo 中泛化引用和使用场景,以及使用 Spring 的方式和基于 Java API 的方式使用泛化引用。同时也分析了泛化引用实现的原理,其实就是经过ReferenceConfig
包装接口名称、调用方法以及参数名称和参数值,再建立GenericService
代理对象而后调用一系列的 Invoker
对象。
本节课程的重点以下:
我的从事金融行业,就任过易极付、思建科技、某网约车平台等重庆一流技术团队,目前就任于某银行负责统一支付系统建设。自身对金融行业有强烈的爱好。同时也实践大数据、数据存储、自动化集成和部署、分布式微服务、响应式编程、人工智能等领域。同时也热衷于技术分享创立公众号和博客站点对知识体系进行分享。关注公众号: 青年IT男 获取最新技术文章推送!
博客地址: http://youngitman.tech
微信公众号: