Java SPI机制

SPI全称Service Provider Interface,是Java提供的一套用来被第三方实现或者扩展的API,它可以用来启用框架扩展和替换组件。
在这里插入图片描述

Java SPI实际上是“基于接口的编程+策略模式+配置文件”组合实现的动态加载机制。


系统设计的各个抽象,往往有很多不同的实现方案,在面向的对象的设计里,一般推荐模块之间基于接口编程,模块之间不对实现类进行硬编码。一旦代码里涉及具体的实现类,就违反了可拔插的原则,如果需要替换一种实现,就需要修改代码。为了实现在模块装配的时候能不在程序里动态指明,这就需要一种服务发现机制。


Java SPI就是提供这样的一个机制:为某个接口寻找服务实现的机制。就是将装配的控制权移到程序之外,在模块化设计中这个机制尤其重要。所以SPI的核心思想就是解耦。


但是SPI也存在缺点,如:

  • 不能按需加载。虽然 ServiceLoader 做了延迟加载,但是只能通过遍历的方式全部获取。如果其中某些实现类很耗时,而且你也不需要加载它,那么就形成了资源浪费
  • 获取某个实现类的方式不够灵活,只能通过迭代器的形式获取

这里就来以实际的代码例子来看一看Java SPI机制的使用,首先我们来看一下项目目录,如下:
在这里插入图片描述

1、定义服务接口

package com.rockvine.spi.service;

public interface SpiDemoService {
    void sayHello();
}

2、写出接口的一个或多个实现

package com.rockvine.spi.service.impl;

import com.rockvine.spi.service.SpiDemoService;

public class SpiDemoServiceImplA implements SpiDemoService {
    @Override
    public void sayHello() {
        System.out.println("Hello SpiDemoServiceImplA");
    }
}
package com.rockvine.spi.service.impl;

import com.rockvine.spi.service.SpiDemoService;

public class SpiDemoServiceImplB implements SpiDemoService {
    @Override
    public void sayHello() {
        System.out.println("Hello SpiDemoServiceImplB");
    }
}
package com.rockvine.spi.service.impl;

import com.rockvine.spi.service.SpiDemoService;

public class SpiDemoServiceImplC implements SpiDemoService {
    @Override
    public void sayHello() {
        System.out.println("Hello SpiDemoServiceImplC");
    }
}

3、在 src/main/resources/ 下建立 /META-INF/services 目录, 新增一个以接口命名的文件

然后里面的内容是要应用的实现类,这里我们一共有3个 SpiDemoService 接口的实现类,这里只配置其中的两个实现类,如下:
在这里插入图片描述


4、使用 ServiceLoader 来加载配置文件中指定的实现

package com.rockvine.spi;

import com.rockvine.spi.service.SpiDemoService;

import java.util.Iterator;
import java.util.ServiceLoader;

public class SpiApp {
    public static void main(String[] args) {
        ServiceLoader<SpiDemoService> services = ServiceLoader.load(SpiDemoService.class);
        Iterator<SpiDemoService> iterator = services.iterator();
        while (iterator.hasNext()){
            SpiDemoService service = iterator.next();
            service.sayHello();
        }
    }
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值