Apache Dubbo的@SPI接口应用

这篇具有很好参考价值的文章主要介绍了Apache Dubbo的@SPI接口应用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

记录:472

场景:使用Apache Dubbo的@SPI接口加载实现类搭建框架。

版本:JDK 1.8,dubbo-common-3.0.0。

SPI全称Service Provider Interface。

1.基础

1.1引用依赖

<dependency>
  <groupId>org.apache.dubbo</groupId>
  <artifactId>dubbo-common</artifactId>
  <version>3.0.0</version>
</dependency>

1.2应用

(1)使用@SPI注解作用在自定义接口com.hub.example.pf.adapter.IPfDataAdapter。

(2)业务类TCityAdapterImpl、TProvinceAdapterImpl等实现接口IPfDataAdapter。

(3)在..\src\main\resources目录下,新建\META-INF\services目录

(4)在\META-INF\services目录新建配置文件:com.hub.example.pf.adapter.IPfDataAdapter,文件名称就是@SPI注解作用的接口全路径名称。

(5)在\META-INF\services\com.hub.example.pf.adapter.IPfDataAdapter配置文件中添加入下内容(key=value键值对):

t_province=com.hub.example.process.adapter.TProvinceAdapterImpl
t_city=com.hub.example.process.adapter.TCityAdapterImpl

(6)根据配置文件中key名称和接口名称获取实现类,如下:

IPfDataAdapter var= ExtensionLoader.getExtensionLoader(IPfDataAdapter.class).getExtension(tableName);

1.3逻辑

Apache Dubbo框架对使用@SPI注解接口,会在..\src\main\resources\META-INF\services目录下扫描配置并加载。

2.示例场景

(1)从某数据源(比如数据库)中读取数据存放在:Map<String, Object> data。

(2)组装成Tuple3<String, String, Map<String, Object>> in数据格式,其中Tuple3第一个参数数:表名称,第二参数:指定的字段名称,第三个参数就是数据。

(3)使用计算框架com.hub.example.pf.function.PfDataMapFunction计算业务

输入:Tuple3<String, String, Map<String, Object>> in;

输出:Tuple3<String, String, Map<String, String>> out;

(4)把Tuple3<String, String, Map<String, String>> out传递给下游处理。比如数据写入到HBase等目的端。

3.示例代码

3.1接口和抽象类

(1)接口IPfDataAdapter

全称:com.hub.example.pf.adapter.IPfDataAdapter

代码:

@SPI
public interface IPfDataAdapter {
    Tuple3<String, String, Map<String, String>> getPfData(Map<String, Object> value);
}

(2)抽象类

全称:com.hub.example.pf.adapter.PfDataAdapterAbstract

代码:

public abstract class PfDataAdapterAbstract implements IPfDataAdapter {
    public PfDataAdapterAbstract() {
    }
    public Tuple3<String, String, Map<String, String>> getPfData(Map<String, Object> data) {
        try {
            Map<String, String> result = new HashMap(data.size());
            for (Map.Entry<String, Object> entry : data.entrySet()) {
                if (entry.getValue() != null) {
                    result.put(entry.getKey(), entry.getValue().toString());
                }
            }
            return new Tuple3(this.getTableName(), this.getRowKeyColumns(), result);
        } catch (Exception e) {
            return new Tuple3(null, null, new HashMap<>());
        }
    }
    public abstract String getDataType();
    public String getTableName() {
        return TableConfig.getTableName(this.getDataType());
    }
    public String getRowKeyColumns() {
        return TableConfig.getRowKeyColumns(this.getDataType());
    }
}

3.2计算框架

全称:com.hub.example.pf.function.PfDataMapFunction

代码:

public class PfDataMapFunction {
    public PfDataMapFunction() {
    }
    public Tuple3<String, String, Map<String, String>> map(Tuple3<String, String, Map<String, Object>> data) {
        try {
            String tableName = (String) data.f0;
            IPfDataAdapter dataAdapter = ExtensionLoader.getExtensionLoader(IPfDataAdapter.class).getExtension(tableName);
            if (dataAdapter == null) {
                return new Tuple3();
            } else {
                return dataAdapter.getPfData((Map) data.f2);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return new Tuple3();
        }
    }
}

3.3业务类

(1)业务类TProvinceAdapterImpl对应表:t_province

全称:com.hub.example.process.adapter.TProvinceAdapterImpl

代码:

public class TProvinceAdapterImpl extends PfDataAdapterAbstract {
    public TProvinceAdapterImpl() {
    }
    @Override
    public String getDataType() {
        return "T_PROVINCE";
    }
    public Tuple3<String, String, Map<String, String>> getPfData(Map<String, Object> data) {
        if (data.get("PROVINCE_ID") == null) {
            return new Tuple3();
        }
        return super.getPfData(data);
    }
}

(2)业务类TCityAdapterImpl对应表:t_city

全称:com.hub.example.process.adapter.TCityAdapterImpl

代码:

public class TCityAdapterImpl extends PfDataAdapterAbstract {
    @Override
    public String getDataType() {
        return "T_CITY";
    }

    public Tuple3<String, String, Map<String, String>> getPfData(Map<String, Object> data) {
        if (data.get("CITY_ID") == null) {
            return new Tuple3();
        }
        return super.getPfData(data);
    }
}

3.4配置文件

(1)配置目录..\META-INF\services

目录:..\src\main\resources\META-INF\services

(2)配置文件com.hub.example.pf.adapter.IPfDataAdapter

文件名:com.hub.example.pf.adapter.IPfDataAdapter

文件内容:

t_province=com.hub.example.process.adapter.TProvinceAdapterImpl
t_city=com.hub.example.process.adapter.TCityAdapterImpl

3.5配置类

全称:com.hub.example.config.TableConfig

代码:

public class TableConfig {
    private static ConcurrentHashMap<String, String> tableConfig = new ConcurrentHashMap<>();
    static {
        tableConfig.put("TABLE:T_PROVINCE", "HUB:T_PROVINCE");
        tableConfig.put("ROW_KEY:T_PROVINCE", "V_DATA_DATE,PROVINCE_ID");
        tableConfig.put("TABLE:T_CITY", "HUB:T_CITY");
        tableConfig.put("ROW_KEY:T_CITY", "V_DATA_DATE,CITY_ID");
    }
    public static String getTableName(String tableName) {
        return tableConfig.get("TABLE:" + tableName.toUpperCase());
    }
    public static String getRowKeyColumns(String tableName) {
        return tableConfig.get("ROW_KEY:" + tableName.toUpperCase());
    }
}

3.6实体类

全称:com.hub.example.api.Tuple3

代码:

public class Tuple3<T0, T1, T2> implements Serializable {
    private static final long serialVersionUID = 1L;
    public T0 f0;
    public T1 f1;
    public T2 f2;

    public Tuple3() {
    }

    public Tuple3(T0 f0, T1 f1, T2 f2) {
        this.f0 = f0;
        this.f1 = f1;
        this.f2 = f2;
    }

    public static String arrayAwareToString(Object o) {
        String arrayString = Arrays.deepToString(new Object[]{o});
        return arrayString.substring(1, arrayString.length() - 1);
    }

    public String toString() {
        return "(" + arrayAwareToString(this.f0) + ";" + arrayAwareToString(this.f1) + ";" + arrayAwareToString(this.f2) + ")";
    }
}

4.示例测试

全称:com.hub.example.process.ExampleApplicationSPI

代码:

public class ExampleApplicationSPI {
    public static void main(String[] args) throws Exception {
        PfDataMapFunction dataPfMapFunction = new PfDataMapFunction();
        //操作t_province
        String table01 = "t_province";
        Map<String, Object> data01 = getTProvince();
        Tuple3<String, String, Map<String, Object>> in01 = new Tuple3(table01, data01.get("PROVINCE_ID"), data01);
        Tuple3<String, String, Map<String, String>> out01 = dataPfMapFunction.map(in01);
        System.out.println("操作表t_province后数据: " + out01.toString());
        //操作t_city
        String table02 = "t_city";
        Map<String, Object> data02 = getTCity();
        Tuple3<String, String, Map<String, Object>> in02 = new Tuple3(table02, data02.get("CITY_ID"), data02);
        Tuple3<String, String, Map<String, String>> out02 = dataPfMapFunction.map(in02);
        System.out.println("操作表t_city后数据: " + out02.toString());
    }
    public static Map<String, Object> getTProvince() {
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("PROVINCE_ID", 33001694333578181L);
        dataMap.put("V_DATA_DATE", "20230910");
        dataMap.put("PROVINCE_NAME", "浙江");
        dataMap.put("GROSS", 7.77D);
        return dataMap;
    }
    public static Map<String, Object> getTCity() {
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("CITY_ID", 33011694333578181L);
        dataMap.put("V_DATA_DATE", "20230911");
        dataMap.put("CITY_NAME", "杭州");
        dataMap.put("GROSS", 1.88D);
        return dataMap;
    }
}

以上,感谢。

2023年9月10日文章来源地址https://www.toymoban.com/news/detail-733231.html

到了这里,关于Apache Dubbo的@SPI接口应用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java——JDK1.8新特性

    目录 一、Lambda 表达式 (一)Lambda 表达式语法 (二)类型推断 二、函数式接口 (一)自定义函数式接口 (二)作为参数传递Lambda 表达式 (三)Java 内置四大核心函数式接口 三、方法引用 四、Stream API (一)什么是Stream? (二)Stream 的操作三个步骤 (三)创建流的四种方

    2024年02月07日
    浏览(87)
  • Java中jdk1.8和jdk17相互切换

    之前做Java项目时一直用的是jdk1.8,现在想下载另一个jdk版本17,并且在之后的使用中可以进行相互切换,我将jdk切换时所遇到的问题记录下来并分享出来供大家参考。 环境变量配置如下: 步骤1 步骤2 (注:@MAVEN_HOME%bin;是配置maven时的环境变量,如果没有安装maven就不用管)

    2024年02月03日
    浏览(63)
  • java jdk1.8下载与安装

    官网下载地址:Java Downloads | Oracle 打开官网链接,下滑至Java 8模块,选取自己电脑适合的版本点击下载 1.找到我们下载的安装包,双击运行 2.点击下一步 3.点击更改,修改安装目录   4.选择合适的安装位置,点击确定   5.点击下一步   6.弹出jre的安装选项,点击更改,修改

    2024年02月08日
    浏览(55)
  • JDK1.8新特性(部分)【Lambda表达式、函数式接口】--学习JavaEE的day41

    day41 JDK1.8新特性简介 速度更快 - 优化底层源码,比如HashMap、ConcurrentHashMap 代码更少 - 添加新的语法Lambda表达式 强大的Stream API 便于并行 最大化减少空指针异常 - Optional Lambda表达式 简介 Lambda是一个匿名函数(方法), 允许把函数作为一个方法的参数 。利用Lambda表达式可以写出

    2024年04月25日
    浏览(36)
  • 深入理解java和dubbo的SPI机制

    本质:将接口实现类的全限定名配置在文件中,并由服务加载器读取配置文件,加载实现类。这样可以在运行时,动态为接口替换实现类。 java SPI:用来设计给服务提供商做插件使用的。基于策略模式来实现动态加载的机制。我们在程序只定义一个接口,具体的实现交个不同

    2024年02月08日
    浏览(48)
  • java jdk1.8.0_221 安装步骤

    一、下载jdk Oracle JDK下载官网https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html下载jdk1.8.0_221. 需要注册账号登陆才能下载。 下载完成,双击jdk-8u221-windows-x64.exe,进行安装。 二、安装jdk 安装前准备工作,D盘新建文件夹JAVA,在JAVA文件夹中新建两个文件夹:jdk和

    2024年02月06日
    浏览(59)
  • [Java]静态代理、动态代理(基于JDK1.8)

    【版权声明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) https://www.cnblogs.com/cnb-yuchen/p/18002823 出自【进步*于辰的博客】 参考笔记一,P83;笔记二,P75.4。 目录 1、概述 2、静态代理的两种形式 2.1 面向接口 2.2 面向继承 3、动态代理的两种形式 3.1 JDK动态代理

    2024年03月09日
    浏览(39)
  • 【Java】jdk1.8 Java代理模式,Jdk动态代理讲解(非常详细,附带class文件)

       📝个人主页:哈__ 期待您的关注  想要学代理模式,我们就要先弄清一个概念 “什么是代理”? 在我们的现实生活中,你或许不少听过关于代理的名词,如:代理商。那什么又叫做代理商?让我一个词来形容就是 中间商。 举个例子,在你买二手房的时候,你一般不会直

    2024年04月15日
    浏览(45)
  • Windows11配置Java8开发环境 - JDK1.8

    1、下载JDK 我们要下载的是Oracle版本的JDK,我们首先进入Oracle的官网的Java下载页面:https://www.oracle.com/cn/java/technologies/downloads/ 一直往下滑 ,找到 Java8 —点击 Windows (如果你是其他系统选择你对应的系统即可)— 在下方根据你的电脑系统类型选择对应的X86或X64然后点击下载

    2024年02月10日
    浏览(50)
  • 【Java】JDK1.8 HashMap源码,put源码详细讲解

       📝个人主页:哈__ 期待您的关注  在Java中,HashMap结构是被经常使用的,在面试当中也是经常会被问到的。这篇文章我给大家分享一下我对于HashMap结构源码的理解。 HashMap的存储与一般的数组不同,HashMap的每一个元素存储的并不是一个值,而是一个引用类型的Node结点,这

    2024年04月13日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包