java之API和SPI
java之API和SPI
JAVA中区分API和SPI都是相对的概念,他们的差别只是在语义上,API直接被应用开发人员使用,API被框架的开发人员使用。
API
大多数情况下,都是实现方来定制接口并完成对接口的不同实现,调用方仅仅依赖却无权选择不同的实现。
SPI
SPI(Service Provider Interface)是JDK内置的一种服务提供发现机制。本质是将接口实现类的全限定名配置在文件中,并由服务加载器读取配置文件,加载实现类。这样可以在运行时,动态为接口替换实现类。
在Java中SPI是被用来设计给服务提供商做插件使用的。基于策略模式来实现动态加载的机制。我们在程序只定义一个接口,具体的实现交个不同的服务提供者;在程序启动的时候,读取配置文件,由配置确定要调用哪一个实现。有很多组件的实现,如日志、数据库访问等都是采用这样的方式,最常用的就是 JDBC 驱动。
SPI代码示例
一、项目目录
二、定义框架接口
public interface Car { boolean isSupport(String name); void start(); void druid(); void stop(); }
三、定于服务提供方实现,并放入WEN-INFO/services/下
定义宝马汽车驱动
public class BmwCar implements Car { private final String BMW = "car:bmw://"; public boolean isSupport(String name) { if(name.startsWith(BMW)){ return Boolean.TRUE; } return Boolean.FALSE; } public void start() { System.out.println("------ 宝马 启动 -----------------"); } public void druid() { System.out.println("------ 宝马 启动中 -----------------"); } public void stop() { System.out.println("------ 宝马 停止 -----------------"); } }
定义奥迪汽车驱动
public class AudiCar implements Car { private final String AUDI = "car:audi://"; public boolean isSupport(String name) { if(name.startsWith(AUDI)){ return Boolean.TRUE; } return Boolean.FALSE; } public void start() { System.out.println("------ 奥迪 启动 -----------------"); } public void druid() { System.out.println("------ 奥迪 启动中 -----------------"); } public void stop() { System.out.println("------ 奥迪 停止 -----------------"); } }
WEN-INFO/services/
四、通过ServiceLorder
public class Test { private final static String NAME = "car:audi://"; public static void main(String[] args) { ServiceLoaderspiLoader = ServiceLoader.load(Car.class); for (Car spi : spiLoader) { if(spi.isSupport(NAME)){ Travel travel = new Travel(spi); travel.go(""); break; } } } }