1.SPI简述
SPI(Service Provider Interface),是JDK内置的一种服务提供发现机制。SPI通过加载ClassPath路径下的META-INF/services文件夹下的所有文件,自动加载文件里所制定的接口实现类。在Dubbo、JDBC(Class.forName("com.mysql.jdbc.Driver")读取MySQL的jar包中的META-INF/services/com.mysql.jdbc.Driver文件)中都使用到了SPI机制。
不足:
ServiceLoader加载META-INF/services/*使用了延迟加载,但只能将实现类全部加载并实例化,然后通过遍历全部获取。
2.代码示例:
2.1 Maven项目结构:
2.2 接口类SpiService.java:
package com.lance.spi.demo.iservice;
public interface SpiService {
void execute();
}
2.3 实现类ComplexSpiServiceImpl.java:
package com.lance.spi.demo.service.impl;
import com.lance.spi.demo.iservice.SpiService;
public class ComplexSpiServiceImpl implements SpiService {
@Override
public void execute() {
System.out.println("ComplexSpiServiceImpl execute.");
}
}
2.4 实现类SimpleSpiServiceImpl.java:
package com.lance.spi.demo.service.impl;
import com.lance.spi.demo.iservice.SpiService;
public class SimpleSpiServiceImpl implements SpiService {
@Override
public void execute() {
System.out.println("SimpleSpiService execute.");
}
}
2.5 com.lance.spi.demo.iservice.SpiService文本文件:
com.lance.spi.demo.service.impl.ComplexSpiServiceImpl
com.lance.spi.demo.service.impl.SimpleSpiServiceImpl
2.6 主类JavaSpiMain.java:
package com.lance.spi.demo.main;
import com.lance.spi.demo.iservice.SpiService;
import sun.misc.Service;
import java.util.Iterator;
import java.util.ServiceLoader;
public class JavaSpiMain {
public static void main(String[] args) {
System.out.println("----------- Service.providers --------------");
Iterator<SpiService> providers = Service.providers(SpiService.class);
while(providers.hasNext()) {
SpiService spiService = providers.next();
spiService.execute();
}
System.out.println("------------ ServiceLoader.load ----------------");
ServiceLoader<SpiService> load = ServiceLoader.load(SpiService.class);
Iterator<SpiService> iterator = load.iterator();
while(iterator.hasNext()) {
SpiService spiService = iterator.next();
spiService.execute();
}
}
}
2.7 输出结果:
----------- Service.providers --------------
ComplexSpiServiceImpl execute.
SimpleSpiService execute.
------------ ServiceLoader.load ----------------
ComplexSpiServiceImpl execute.
SimpleSpiService execute.