Java中SPI应用

SPI介绍

Java中SPI的概念是一种服务发现的机制,从1.6开始支持该功能。具体来说就是一个接口有多个实现的时候,可以通过SPI动态加载具体实现。

源码再现

从1.6开始,增加了java.util.ServiceLoader类,用于扫描某个接口的具体实现类。

public final class ServiceLoader
    implements Iterable
{

    private static final String PREFIX = "META-INF/services/";

    // The class or interface representing the service being loaded
    private final Class service;

    // The class loader used to locate, load, and instantiate providers
    private final ClassLoader loader;

从源码看出,ServiceLoader是一个泛型类,可以指定某个接口,它会扫描META-INF/services/路径下以相关接口的全路径类名命名的文件,文件中写入所有需要扫描的实现类名即可。

举个例子

1.首先定义一个接口SpiInterface,假如包名为com.spi.test
2.再定义它的若干实现类,假如包名为com.spi.test.impl
3.在META-INF/services/新建文件com.spi.test.SpiInterface

com.spi.test.impl.ASpiInterface
com.spi.test.impl.CSpiInterface
com.spi.test.impl.BSpiInterface

4.通过ServiceLoader获取实现

        ServiceLoader loaders = ServiceLoader.load(SpiInterface.class);
        for (SpiInterfacein : loaders) {
            in.sayHello();
        }

应用场景

1.厂家定义接口,如老版本的sql驱动等
2.日志统一接口
3.api版本控制,不同的版本实现可以用继承,根据不同的版本号找对应的实现类

替代方案

自己完成类似SPI的功能,可以使用普通的类加载器去动态加载实现类,也可以使用spring的import org.springframework.context.ApplicationContext获取。但SPI实现更简单,而且api内置集成,推荐使用。

样列源码

  • zj-learn中spi包下代码。

你可能感兴趣的:(Java中SPI应用)