public interface SpiDemo { void say(); }
public class SpiDemoImpl1 implements SpiDemo { public void say() { System.out.println("SpiDemoImpl1"); } }
每一个SPI接口都需要在自己项目的静态资源目录中声明一个services文件,文件名为实现规范接口的类名全路径。在resources目录中创建\META-INF\services目录,创建以com.hanggle.spi.api.SpiDemo为名的文件。(文件名即是要实现的接口类的全路径如下图)
文件内容:
com.hanggle.spi.api.impl1.SpiDemoImpl1
public class SpiDemoImpl2 implements SpiDemo { public void say() { System.out.println("SpiDemoImpl2"); } }
同spi-demo-impl1一样
在resources目录中创建\META-INF\services目录,创建以com.hanggle.spi.api.SpiDemo为名的文件。
文件内容:
com.hanggle.spi.api.impl1.SpiDemoImpl2
public static void main(String[] args) { ServiceLoader<SpiDemo> serviceLoader = ServiceLoader.load(SpiDemo.class); for (SpiDemo o : serviceLoader) { o.say(); } }
运行结果:
java SPI应用场景很广泛,在Java底层和一些框架中都很常用,比如java数据驱动加载和Dubbo。Java底层定义加载接口后,由不同的厂商提供驱动加载的实现方式,当我们需要加载不同的数据库的时候,只需要替换数据库对应的驱动加载jar包,就可以进行使用。
原文:https://www.cnblogs.com/oskyhg/p/10800051.html