什么是SPI

SPI全称Service Provider Interface。简单理解就是一个不用依赖Spring框架即可简易实现ioc容器的一个技术手段。

SPI机制

JDK-SPI

JDK 提供了一个java.util.ServiceLoader类用于在指定路径META-INF/services下发现服务。

在指定路径下新建名字为接口全名的文件,然后里面配置实现类的全名。
新建配置文件

public interface JDKSPIService {
    void sayHello();
}

public class JDKSPIImpl1 implements JDKSPIService {
    @Override
    public void sayHello() {
        System.out.println("impl1, hello!");
    }
}

public class JDKSPIImpl2 implements JDKSPIService {
    @Override
    public void sayHello() {
        System.out.println("Impl2, hello!");
    }
}

// 测试类
public class SPITest {
    @Test
    public void testJDKSPI(){
        ServiceLoader<JDKSPIService> load = ServiceLoader.load(JDKSPIService.class);

        for (JDKSPIService service : load) {
            service.sayHello();
        }
    }
}

// 输出
impl1, hello!
Impl2, hello!

@AutoService - SPI

google提供了一个包,可以使用注解@AutoService,简化上述流程,不需要手动在指定路径下新建注册文件,而是通过该注解,在编译过程中自动创建这个注册文件。

这个注解需要依赖两个包,缺一不可,一个是注解处理器,一个是实现。

    <dependencies>
        <dependency>
            <groupId>com.google.auto.service</groupId>
            <artifactId>auto-service-annotations</artifactId>
            <version>1.0</version>
        </dependency>

        <dependency>
            <groupId>com.google.auto.service</groupId>
            <artifactId>auto-service</artifactId>
            <version>1.0</version>
        </dependency>
    </dependencies>

示例:

public interface SPIService {
    void sayHello();
}

@AutoService(SPIService.class)
public class SPIImpl1 implements SPIService {
    @Override
    public void sayHello() {
        System.out.println("impl1, hello!");
    }
}

@AutoService(SPIService.class)
public class SPIImpl2 implements SPIService{
    @Override
    public void sayHello() {
        System.out.println("Impl2, hello!");
    }
}

// 测试类
public class SPITest {
    @Test
    public void test() {
        ServiceLoader<SPIService> load = ServiceLoader.load(SPIService.class);

        for (SPIService service : load) {
            service.sayHello();
        }
    }
}

// 输出
impl1, hello!
Impl2, hello!

参考

ServiceLoader解析
https://blog.csdn.net/Love667767/article/details/106373672

AutoService解析
https://blog.csdn.net/Love667767/article/details/106422787

最后修改:2021 年 12 月 28 日
如果觉得我的文章对你有用,请随意赞赏