什么是spi
spi全名为service provider interface,它是一种api,该api允许被第三方扩展和替换。
面向对象设计里提倡基于接口编程,一旦代码中涉及到具体的实现。而第三方引用该模块时发现其具体实现不满足要求那么就需要动态的替换器实现类。当各模块装配的时候SPI会为模块A中的接口A1寻找其具体的服务实现机制(该服务实现机制很有可能存在于模块B中)。
怎么写spi
在一些基础组件中我们会使用java.sql.Driver接口构建数据库操作抽象,等到具体项目装配时才会根据具体数据库获得对应的实现。
假如当我们使用mysql驱动的时候会把mysql包引进来
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.6</version>
</dependency>
在mysql-connector-java.6.0.6.jar包中,META-INF/services就包含了其java.sql.Driver的具体实现,如下图所示:
image.png
怎么去寻找服务
寻找服务就是需要把外部实现class加载进来,java虚拟机是按需加载类机制。
java.util.serviceLoader会去META-INF下把所有的实现类都加载进来。
ServiceLoader<ILoader> class1 = ServiceLoader.load(ILoader.class);
for (ILoader iLoader :class1)
{
iLoader.doLoader();
}
上述代码具体的service实现如下图:
image.png
这样写有什么用?我们一般写代码会是如下方式:
class AImpl implement InterA
{
}
class Demo{
InterA a = new AImpl();
a.XXXX;
}
而有了SPI我们可以这样写:
class Demo1{
ServiceLoader<InterA> aObjects = ServiceLoader.load(InterA.class);
for (InterA aObj :aObjects)
{
aObj.XXX;//不需要把具体类写入进来。
}
}
网友评论