你們好,今天開始給你們分享 — 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
微信公衆號: