Java:SPI机制

【参考文章】:Java SPI机制详解

【参考文章】:JDK和Spring中SPI的实现原理和区别

【参考文章】:理解的Java中SPI机制

1. 简介

  SPI 全称为 (Service Provider Interface) ,是JDK内置的一种服务提供发现机制,通过该方式可实现插件化开发;

  一般是Java定义了API接口,由第三方进行实现,程序运行时动态加载第三方的实现类,根据第三方的具体实现完成接口的功能;

2. 使用方式

  1. 定义一个 interface 接口;

  2. 第三方实现该接口,完成具体功能的实现;

  3. 主程序运行时通过 ServiceLoader.load(Plugin.class)加载具体实现类;

  4. 加载时扫描主程序 META-INF/services 目录下文件,文件名以接口的完全限定名(包名+类名)命名,文件内容是该接口的具体实现类的完全限定名,可以有多个实现类,通过Iterator的方式遍历实现类来加载;

  5. 主程序会将所有的实现类全部加载到程序中;

3. 示例

  Java定义了 java.sql.Driver接口,但是没有实现,具体的实现由第三方提供。  

  JDBC4.0之前,连接数据库的时候,通常会用Class.forName("com.mysql.cj.jdbc.Driver")加载数据库相关的驱动,然后再进行获取连接等的操作。

  JDBC4.0之后不需要Class.forName来加载驱动,直接获取连接即可,这里就是使用了Java的SPI机制来实现,程序运行时自动加载了实现类;

  

 4. 扩展

  Spring对SPI机制进行了扩展,可以自动将配置类或者bean自动加载到IOC容器,典型的实现就是Spring Boot 的 @EnableAutoConfiguration;

  Spring中使用的类是SpringFactoriesLoader,在org.springframework.core.io.support包中,默认加载 META-INF/spring.factories文件,文件内容是需要加载类的完全限定名

  比如 Mybtis的starter依赖:

  

5.  总结

5.1 优点

  使用Java SPI机制的优势是实现解耦,使得第三方服务模块的装配控制的逻辑与调用者的业务代码分离。应用程序可以根据实际业务情况启用框架扩展或替换框架组件。

5.2 缺点

  加载实现类的方式不够灵活;

  多个并发多线程使用ServiceLoader类的实例是不安全的;

  

猜你喜欢

转载自www.cnblogs.com/virgosnail/p/12740029.html