什么是SPI机制

1.SPI介绍

SPI的全名是Service Provider Interface, JDK 内置的一种服务提供机制,用于提升接口的可扩展性,其最终的目的是用于模块之间的解耦,减少相互依赖。

2.SPI的用法

  1. 服务的提供方对调用方的接口提供了一种实现, 在jar包中resource的META-INF/services目录下创建一个接口的全限定名的文件,该文件的内容是是实现类的全限定名;
  2. 在主程序中使用java的util包中的ServiceLoader加载该接口从而获取该实现类;
  3. 实现类要带一个无参构造;

3.SPI的简单Demo

SPI 的Demo结构

SPI 的Demo代码

//定义接口
public interface PayMethod {void getPayMethod();
}
//两个实现类
public class AliPayMethod implements PayMethod {@Overridepublic void getPayMethod() {System.out.println("ali pay");}
}
public class WechatPayMethod implements PayMethod {@Overridepublic void getPayMethod() {System.out.println("wechat pay");}
}
//主程序
public class SPIDemo {public static void main(String[] args) {ServiceLoader<PayMethod> payMethods = ServiceLoader.load(PayMethod.class);Iterator<PayMethod> iterable = payMethods.iterator();while (iterable.hasNext()){System.out.println(iterable.next());}}
}//文件
com.dev.impl.WechatPayMethod
com.dev.impl.AliPayMethod

上述输出是两个实现类的对象地址。如果你是maven项目的话,请使用jar工程,POM工程是不生效的。

4.SPI的实际应用

  • 数据驱动加载。JDBC4.0
    private static void loadInitialDrivers() {String drivers;try {drivers = AccessController.doPrivileged(new PrivilegedAction<String>() {public String run() {return System.getProperty("jdbc.drivers");}});} catch (Exception ex) {drivers = null;}AccessController.doPrivileged(new PrivilegedAction<Void>() {public Void run() {ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class);Iterator<Driver> driversIterator = loadedDrivers.iterator();try{while(driversIterator.hasNext()) {driversIterator.next();}} catch(Throwable t) {// Do nothing}return null;}});
......
}
  • servlet 3.0 提供自定义组件的初始化工
    就servlet 3.0自定义组件的初始化而言,Spring官网也是通过要求实现WebApplicationInitializer来减少web.xml的配置。点击此处
    Servlet初始化自定义组件过程:
  1. 在启动web容器时,会自动扫描META-INF/services目录下的文件,并将文件中的类实例化;
  2. Spring通过使用SpringServletContainerInitializer实现ServletContainerInitializer, 从而在容器启动时会执行onStartup方法;
  3. Spring此时为了扩展性重新定义了一个WebApplicationInitializer的接口,@HandlesTypes会将WebApplicationInitializer的所有实现类作为一个set参数传入;
  4. SpringServletContainerInitializer会执行WebApplicationInitializer所有的实现类中onStartup方法进而实现开发者自定义组件的初始化;

(上述图片来源于网络,侵删)

本文链接:https://my.lmcjl.com/post/19370.html

展开阅读全文

4 评论

留下您的评论.