什么是SPI
SPI全称Service Provider Interface。简单理解就是一个不用依赖Spring框架即可简易实现ioc容器的一个技术手段。
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