Dubbo 泛化引用

前言

你們好,今天開始給你們分享 — Dubbo 專題之 Dubbo 泛化引用。在前一個章節中咱們介紹了 Dubbo 中的參數驗證以及使用場景。咱們在這個章節會繼續介紹 Dubbo 泛化引用。那麼什麼是泛化引用呢?泛化引用有什麼做用呢?下面就讓我詳細瞭解下吧!java

1. 泛化引用簡介

在前面的章節中咱們編寫的 Dubbo 服務都是基於 API 接口,例如:com.muke.dubbocourse.common.api.BookFacade接口。咱們在平常開發中的步驟都是首先定義好暴露服務的 API 接口,而後把這個接口打包成 jar 提供給服務調用方。也就是說一般狀況下咱們的服務調用方都會依賴咱們定義的 API 接口編程。那麼在 Dubbo 中爲咱們提供一種不須要依賴 API 接口的方式進行服務調用,這種方式就泛化引用。其表示類爲GenericServicegit

2. 使用方式

在這裏咱們主要介紹兩種使用方式:spring

  1. 經過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);
  1. 經過 Java API方式使用
// 引用遠程服務 
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});

3. 使用場景

從泛化引用自己咱們能夠知道它是不須要 API 接口,也就是說泛化引用使用場景在服務提供方沒有明確的 API 接口提供的狀況下咱們均可以使用。一般用於框架集成,好比:實現一個 Dubbo 服務對外統一網,就可經過 GenericService 調用後端全部服務實現。 例如:後端

泛化調用

在上面的圖中客戶端經過統一的Dubbo網關訪問後端全部的 Dubbo 服務,這裏就是使用 泛化調用實現。api

4. 示例演示

下面咱們經過兩種方式來演示一個獲取圖書列表的服務。數組

  1. 使用 Spring 泛化引用
  • 主要看消費端 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();
    
        }
    
    }
  1. 使用 Java API 方式
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方法。

5. 實現原理

在上面的代碼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 對象,時序圖以下:

泛化引用時序圖

6. 小結

在本小節中咱們主要學習了 Dubbo 中泛化引用和使用場景,以及使用 Spring 的方式和基於 Java API 的方式使用泛化引用。同時也分析了泛化引用實現的原理,其實就是經過ReferenceConfig包裝接口名稱、調用方法以及參數名稱和參數值,再建立GenericService代理對象而後調用一系列的 Invoker 對象。

本節課程的重點以下:

  1. 理解 Dubbo 中泛化引用
  2. 瞭解了兩種泛化引用使用方式
  3. 瞭解泛化引用實現原理
  4. 瞭解泛化引用使用場景

做者

我的從事金融行業,就任過易極付、思建科技、某網約車平臺等重慶一流技術團隊,目前就任於某銀行負責統一支付系統建設。自身對金融行業有強烈的愛好。同時也實踐大數據、數據存儲、自動化集成和部署、分佈式微服務、響應式編程、人工智能等領域。同時也熱衷於技術分享創立公衆號和博客站點對知識體系進行分享。關注公衆號: 青年IT男 獲取最新技術文章推送!

博客地址: http://youngitman.tech

微信公衆號:

相關文章
相關標籤/搜索