浅谈Java中的SPI

1.SPI 简介

SPI 全称为 Service Provider Interface,是一种服务发现机制。

SPI 的本质是将接口实现类的全限定名配置在文件中,并由服务加载器读取配置文件,加载实现类。

这样可以在运行时,动态为接口替换实现类。正因此特性,我们可以很容易的通过 SPI 机制为我们的程序提供拓展功能。

简单来说,就是在程序运行的时候,通过/META-INF/services/下的配置文件来决定加载实现类。

Java SPI

一般命名规则是接口包类名的全称,比如 mysql-connector-java-5.1.49.jar 的文件名叫 java.sql.Driver但是里面的内容就是实现类的包类名全称com.mysql.cj.jdbc.Driver

使用的时候,可以通过ServiceLoader<Robot> serviceLoader = ServiceLoader.load(Driver.class);来获取配置加载实现类

举个例子:
写一个接口类,就叫WaiMai

package com.inkyi.blog.example.spi;

public interface Waimai {
    void songWaiMai();
}

再写两个子类 饿了么 和 美团

package com.inkyi.blog.example.spi;

public class EleMeWm implements Waimai {
    @Override
    public void songWaiMai() {
        System.out.println("饿了么送外卖");
    }
}
package com.inkyi.blog.example.spi;

public class MeituanWm implements Waimai {
    @Override
    public void songWaiMai() {
        System.out.println("美团送外卖");
    }
}

接着在META-INF/services下新建一个文件,名字叫:com.inkyi.blog.example.spi.Waimai内容如下

com.inkyi.blog.example.spi.EleMeWm

最后我们编写测试类

package com.inkyi.blog.example.spi;

import java.util.ServiceLoader;

public class SpiTest {
    public static void main(String[] args) {
        ServiceLoader<Waimai> load = ServiceLoader.load(Waimai.class);
        for (Waimai demo : load) {
            demo.songWaiMai();
        }
    }
}

执行后,Java会根据Waimai.class的包路径,找到META-INF/services下的com.inkyi.blog.example.spi.Waimai文件读取里面的内容,根据内容实例化类,然后执行songWaiMai()方法。

饿了么送外卖

大概的流程就是这样的,由于ServiceLoader实现了Iterable接口,所以com.inkyi.blog.example.spi.Waimai文件中可以写多个实现类,。
比如把美团和饿了么都加上

com.inkyi.blog.example.spi.MeituanWm
com.inkyi.blog.example.spi.EleMeWm

那么就会输出:

美团送外卖
饿了么送外卖

代码案例
META-INF/services

posted @ 2021-06-24 18:29  InkYi  阅读(223)  评论(0编辑  收藏  举报