1.SPI介绍
SPI的全名是Service Provider Interface
, JDK 内置的一种服务提供机制,用于提升接口的可扩展性,其最终的目的是用于模块之间的解耦,减少相互依赖。
2.SPI的用法
- 服务的提供方对调用方的接口提供了一种实现, 在jar包中resource的
META-INF/services
目录下创建一个接口的全限定名的文件,该文件的内容是是实现类的全限定名; - 在主程序中使用java的util包中的
ServiceLoader
加载该接口从而获取该实现类; - 实现类要带一个无参构造;
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初始化自定义组件过程:
- 在启动web容器时,会自动扫描META-INF/services目录下的文件,并将文件中的类实例化;
- Spring通过使用
SpringServletContainerInitializer
实现ServletContainerInitializer
, 从而在容器启动时会执行onStartup
方法; - Spring此时为了扩展性重新定义了一个
WebApplicationInitializer
的接口,@HandlesTypes
会将WebApplicationInitializer
的所有实现类作为一个set参数传入; SpringServletContainerInitializer
会执行WebApplicationInitializer
所有的实现类中onStartup
方法进而实现开发者自定义组件的初始化;
(上述图片来源于网络,侵删)
本文链接:https://my.lmcjl.com/post/19370.html
展开阅读全文
4 评论