【转】使用Java SPI简单示例

PunkLu 2020年01月13日 54次浏览
使用Java SPI简单示例

本文转载自 linkedkeeper.com

SPI扩展

SPI 全称为 Service Provider Interface,是一种服务发现机制。SPI 的本质是将接口实现类的全限定名配置在文件中,并由服务加载器读取配置文件,加载实现类。这样可以在运行时,动态为接口替换实现类。正因此特性,我们可以很容易的通过 SPI 机制为我们的程序提供拓展功能。

SPI

SPI示例

Java SPI示例

本节通过一个示例演示 Java SPI 的使用方法。首先,我们定义一个接口,名称为 Robot。

package tech.punklu.spi.spi;

public interface Robot {
    void sayHello();
}

接下来定义两个实现类,分别为 OptimusPrime 和 Bumblebee。

package tech.punklu.spi.spi;

public class OptimusPrime implements Robot {

    @Override
    public void sayHello() {
        System.out.println("Hello, I am Optimus Prime.");
    }
}
package tech.punklu.spi.spi;

public class Bumblebee implements Robot {

    @Override
    public void sayHello() {
        System.out.println("Hello, I am Bumblebee.");
    }
}

在 src/main/resources/ 下建立 /META-INF/services 目录,新建一个文件,名称为 Robot 的全限定名 org.apache.spi.Robot。

文件位置:

- src
    -main
        -resources
            - META-INF
                - services
                    - tech.punklu.spi.spi;

之所以要新建/META-INF/services目录,是因为在下面用到的java.util.ServiceLoader中指定了前缀为/META-INF/services。

文件内容为实现类的全限定的类名,如下:

tech.punklu.spi.spi.Bumblebee
tech.punklu.spi.spi.OptimusPrime

需要注意的是,调用的顺序与在文件在声明的顺序有关,将按照文件中声明顺序开始执行。

接下来编写代码进行测试:

public class JavaSPITest {

    @Test
    public void sayHello() throws Exception {
        ServiceLoader<Robot> serviceLoader = ServiceLoader.load(Robot.class);
        System.out.println("Java SPI");
        for (Robot robot : serviceLoader) {
            robot.sayHello();
        }
    }
}

测试结果:

Java SPI
Hello, I am Bumblebee.
Hello, I am Optimus Prime.