专栏首页Java技术栈Java SPI 与 Dubbo SPI 有什么区别?

Java SPI 与 Dubbo SPI 有什么区别?

作者:废物大师兄 来源:www.cnblogs.com/cjsblog/p/14346766.html

SPI(Service Provider Interface)是JDK内置的一种服务提供发现机制。本质是将接口实现类的全限定名配置在文件中,并由服务加载器读取配置文件,加载实现类。这样可以在运行时,动态为接口替换实现类。

在Java中SPI是被用来设计给服务提供商做插件使用的。基于策略模式来实现动态加载的机制。我们在程序只定义一个接口,具体的实现交个不同的服务提供者;在程序启动的时候,读取配置文件,由配置确定要调用哪一个实现。有很多组件的实现,如日志、数据库访问等都是采用这样的方式,最常用的就是 JDBC 驱动。

1、Java SPI

核心类:java.util.ServiceLoader

服务是一组众所周知的接口和(通常是抽象的)类。服务提供者是服务的特定实现。提供者中的类通常实现接口,并子类化服务本身中定义的类。服务提供者可以以扩展的形式安装在Java平台的实现中,即放置在任何常见扩展目录中的jar文件。提供程序也可以通过将它们添加到应用程序的类路径或其他特定于平台的方法来提供。

通过在资源目录META-INF/services中放置一个提供程序配置文件来识别服务提供程序。文件名是服务类型的完全限定二进制名称。该文件包含具体提供程序类的完全限定二进制名的列表,每行一个。每个名称周围的空格和制表符以及空白行将被忽略。注释字符是'#';在每一行中,第一个注释字符之后的所有字符都将被忽略。文件必须用UTF-8编码。

按照上面的方法,我们来写个例子试一下

首先,定义一个接口Car

package org.example;

public interface Car {
    void run();
}

两个实现类

ToyotaCar.java

package org.example;

public class ToyotaCar implements Car {
    @Override
    public void run() {
        System.out.println("Toyota");
    }
}

HondaCar.java

package org.example;

public class HondaCar implements Car {
    @Override
    public void run() {
        System.out.println("Honda");
    }
}

在META-INF/services下创建一个名为org.example.Car的文本文件

org.example.ToyotaCar
org.example.HondaCar

最后,写个测试类运行看一下效果

package org.example;

import java.util.ServiceLoader;

public class App
{
    public static void main( String[] args )
    {
        ServiceLoader<Car> serviceLoader = ServiceLoader.load(Car.class);
        serviceLoader.forEach(x->x.run());
    }
}

跟一下ServiceLoader的代码,看看是怎么找到服务实现的

用当前线程的类加载器加载

接口和类加载器都有了,万事俱备只欠东风

另外,Java 核心技术系列教程和示例源码整理好了:https://github.com/javastacks/javastack

Java SPI 不足之处:

2、Dubbo SPI

Dubbo重新实现了一套功能更强的SPI机制, 支持了AOP与依赖注入,并且利用缓存提高加载实现类的性能,同时支持实现类的灵活获取。

<dependency>
      <groupId>org.apache.dubbo</groupId>
      <artifactId>dubbo</artifactId>
      <version>2.7.8</version>
</dependency>

核心类:org.apache.dubbo.common.extension.ExtensionLoader

先来了解一下@SPI注解,@SPI是用来标记接口是一个可扩展的接口

改造一下前面的例子,在Car接口上加上@SPI注解

package org.example;

import org.apache.dubbo.common.extension.SPI;

@SPI
public interface Car {
    void run();
}

两个实现类不变。Spring Boot 学习笔记分享给你学习下、

在META-INF/dubbo目录下创建名为org.example.Car的文本文件,内容如下(键值对形式):

toyota=org.example.ToyotaCar
honda=org.example.HondaCar

编写测试类:

package org.example;

import org.apache.dubbo.common.extension.ExtensionLoader;

import java.util.ServiceLoader;

public class App
{
    public static void main( String[] args )
    {
        //  Java SPI
        ServiceLoader<Car> serviceLoader = ServiceLoader.load(Car.class);
        serviceLoader.forEach(x->x.run());

        //  Dubbo SPI
        ExtensionLoader<Car> extensionLoader = ExtensionLoader.getExtensionLoader(Car.class);
        Car car = extensionLoader.getExtension("honda");
        car.run();
    }
}

下面跟一下代码

如果缓存Map中有,直接返回,没有则加载完以后放进去

加载策略到底是怎样的呢?

到这里就有点明白了,又看到了熟悉的ServiceLoad.load(),这不是刚才讲的Java SPI嘛。另外,微信搜索Java技术栈,在后台回复:面试,可以获取我整理的 Dubbo 系列面试题和答案,非常齐全。

回到之前策略那个地方,将策略按顺序排列,依次遍历所有的策略来加载。就是在那三个目录下查找指定的文件,并读取其中的内容

跟之前的ServiceLoader如出一辙

遇到@Adaptive标注的就缓存起来

最后,大家关注公众号Java技术栈,在后台回复:面试,可以获取我整理的 Java、Dubbo 系列面试题和答案,非常齐全。

本文分享自微信公众号 - Java技术栈(javastack),作者:点击关注 ????

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2021-06-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • JDK/Dubbo/Spring 三种 SPI 机制,谁更好?

    举个栗子,现在我们设计了一款全新的日志框架:super-logger 。默认以XML文件作为我们这款日志的配置文件,并设计了一个配置文件解析的接口:

    芋道源码
  • Dubbo 源码分析 - SPI 机制

    SPI 全称为 Service Provider Interface,是 Java 提供的一种服务发现机制。SPI 的本质是将接口实现类的全限定名配置在文件中,...

    田小波
  • JDK、Dubbo、Spring 三种 SPI 机制,谁更好?

    公众号运营至今,离不开小伙伴们的支持。为了给小伙伴们提供一个互相交流的平台,特地开通了官方交流群。关注公众号「Java后端技术全栈」回复「进群」即可。

    田维常
  • Dubbo SPI 实现原理

    Dubbo 并未使用 Java SPI ,而是重新设计了一套增强版的 SPI 。Dubbo SPI 的相关逻辑封装在了 ExtensionLoader 类中...

    王小明_HIT
  • 【JavaP6大纲】Dubbo篇:Dubbo SPI 和 Java SPI 区别?

    spi 是啥?spi,简单来说,就是 service provider interface ,说白了是什么意思呢,比如你有个接口,现在这个接口有 3 个实现类,...

    java_wxid
  • 深入理解Dubbo源码(二),分析Java SPI与Dubbo SPI的实现源码

    我在上一篇说了句:为什么我能短短几个晚上的时间就能看懂。dubbo不是这么容易完全看懂的,实际上我从国庆之前就开始一点点去了解dubbo,当前我所说的看懂,也只...

    Java艺术
  • dubbo天天用,你不会连SPI都不知道吧?

    继续深入问呗,前面一些基础性的东西问完了,确定你应该都 ok,了解 dubbo 的一些基本东西,那么问个稍微难一点点的问题,就是 spi,先问问你 spi 是啥...

    良月柒
  • dubbo天天用,你不会连SPI都不知道吧?

    继续深入问呗,前面一些基础性的东西问完了,确定你应该都 ok,了解 dubbo 的一些基本东西,那么问个稍微难一点点的问题,就是 spi,先问问你 spi 是啥...

    Bug开发工程师
  • 【Dubbo源码】SPI机制源码解析

    SPI 全称为 Service Provider Interface,是一种服务发现机制。SPI 的本质是将接口实现类的全限定名配置在文件中,并由服务加载器读取...

    石臻臻的杂货铺[同名公众号]
  • 大厂面试系列(五):Dubbo和Spring Cloud

    zhaozhen
  • 三歪问我Dubbo的SPI机制是啥?

    上一篇 Dubbo 文章敖丙已经带了大家过了一遍整体的架构,也提到了 Dubbo 的成功离不开它采用微内核设计+SPI扩展,使得有特殊需求的接入方可以自定义扩展...

    敖丙
  • dubbo 的 spi 思想

    spi,简单来说,就是 service provider interface,说白了是什么意思呢,比如你有个接口,现在这个接口有 3 个实现类,那么在系统运行的...

    IT技术小咖
  • Dubbo——SPI及自适应扩展原理

    Dubbo虽然已交由apache管理,并且社区活跃度也不如SpringCloud,但也是国内应用比较广泛的RPC框架,其背后的设计思想非常值得我们学习借鉴。鉴于...

    夜勿语
  • Dubbo源码分析—SPI扩展

    站在一个框架作者的角度来说,定义一个接口,自己默认给出几个接口的实现类,同时 允许框架的使用者也能够自定义接口的实现。现在一个简单的问题就是:如何优雅的根据一个...

    用户5325874
  • Java SPI机制的运行原理是什么?

    SPI的全称是(Service Provider Interface)是服务提供接口的意思。如果我们不写框架性代码或者开发插件的话,对于SPI机制可能不会那么熟...

    用户5927304
  • Java SPI原理与源码分析

    SPI是Service Provider Interface的缩写,jdk1.6版本开始内置的一种扩展机制,主要用于扩展框架的能力,其实就是框架定义一种能力(规...

    叔牙
  • 面霸篇:Dubbo 夺命 17 问

    Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。

    码哥字节
  • 突破Java面试(36)-聊聊Dubbo的SPI机制

    前面基础性的东西问完了,确定你应该了解Dubbo,那么自然问个稍微难的问题,就是SPI,先问问你这是个啥,然后问问你怎么实现的!

    JavaEdge
  • Java是如何实现自己的SPI机制的? JDK源码(一)

    这是【源码笔记】的JDK源码解读的第一篇文章,本篇我们来探究Java的SPI机制的相关源码。

    源码笔记

扫码关注云+社区

领取腾讯云代金券