java Spi、springSpi、dubboSpi

java Spi、springSpi、dubboSpi

1、Java SPI(Service Provider Interface)一种服务发现机制

它允许服务提供者实现服务接口,并将其实现放置在 JAR 文件中,使得服务消费者可以在运行时动态加载和使用这些实现。Java SPI 主要通过配置文件 META-INF/services/ 实现,配置文件中列出服务接口实现类的全限定名。

Java SPI 示例

假设我们有一个服务接口 Robot,和两个实现类 OptimusPrimeBumblebee

public interface Robot {
    void run();
}


public class OptimusPrime implements Robot {
    @Override
    public void run() {
        System.out.println("Run on the ground");
    }
}


public class Bumblebee implements Robot {
    @Override
    public void run() {
        System.out.println("Run in the water");
    }
}

META-INF/services/ 目录下创建一个文件,文件名为 Robot 的全限定名,内容为实现类的全限定名:

在运行时,可以使用 ServiceLoader 动态加载服务实现:

ServiceLoader<Robot>  loader = ServiceLoader.load(Robot.class) ;

Iterator<Robot> iterator = loader.iterator();

while(iterator.hasNext()){

//顺序读取实现类

}

缺点:

①、不能按需加载(可以解决:重新实现它读取加载文件的方式,在内存建立索引,以此来实现快速动态获取指定实现并加载,同时监听文件修改内容,同步刷新内存,这是基于内存式设计,或者基于文件扫描来获取

②、获取某个实现类的方式不够灵活,只能通过Iterator方式获取

③、并发多线程使用ServiceLoader类的实例不安全

2、spring Spi

springSpi沿用javaspi的设计思想,采用的是‘spring.factories’方式实现spi机制,可以在不修改spring源码的前提下,提高spring框架的扩展性 。

调用SpringFactoriesLoader.loadFactories()方法加载接口所有实现类的实例

List<TestService> list = SpringFactoriesLoader.loadFactories(
TestService.class,Thread.currentThread().getContextClassLoader() )

Spring SPI 是一个spring.factories 配置文件存放多个接口及对应的实现类,以接口全限定名作为key,实现类作为value来配置,多个实现类用逗号隔开,仅`spring.factories`一个配置文件。

和 Java SPI 一样,Spring SPI 也无法获取某个固定的实现,只能按顺序获取所有实现。

(spring特殊实现按需加载:       ApplicationContext context = new AnnotationConfigApplicationContext();

// 根据条件选择特定的实现类

DataProcessingService selectedService = context.getBean("cn.infinite.cascade.partial.service.api.PartialCircuitCascadeServiceImpl",  DataProcessingService.class);

if (selectedService != null) {

selectedService.processData(); }

3、Dubbo SPI

Dubbo SPI 是一种更为灵活的服务扩展机制,基于 Java SPI的缺陷无法支持按需加载接口实现类,Dubbo 并未使用Java SPI, 而是重新实现了一套功能更强的 SPI 机制,包括自动注入、AOP 拦截器、适配器等。

Dubbo SPI的相关逻辑被封装在了 ExtensionLoader 类中,通过ExtensionLoader,我们可以加载指定的实现类。

Dubbo SPI所需的配置文件需放置在`META-INF/dubbo`路径下,配置内容如下:与 Java SPI实现类配置不同,Dubbo SPI是通过键值对的方式进行配置,这样我们可以按需加载指定的实现类。

另外,在测试 Dubbo SPI时,需要在 Robot 接口上标注 @SPI 注解。

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


public class OptimusPrime implements Robot {
    @Override
    public void run() {
        System.out.println("Run on the ground");
    }
}


public class Bumblebee implements Robot {
    @Override
    public void run() {
        System.out.println("Run in the water");
    }
}

在运行时,可以使用 Dubbo 的扩展加载机制动态加载服务实现:

ExtensionLoader<Robot> loader = ExtensionLoader.getExtensionLoader(Robot.class);
Robor optimusPrime = loader.getExtension(optimusPrime);
Robor bumblebee= loader.getExtension(bumblebee);

这些 SPI 机制提供了灵活的扩展点和服务发现机制,能够在不同场景下满足不同的需求。

Java SPI 适用于静态的服务加载,Spring SPI 适用于 Spring 容器的生命周期扩展,而 Dubbo SPI 则提供了更加灵活和强大的服务扩展机制

  • 7
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

江湖中的阿龙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值