java spi

ddatsh

dev #java

Service Provider Interface

“接口+策略模式+配置文件” 组合实现的动态加载机制

SPI 应用之一是可替换的插件机制

  1. 定义一组接口

  2. 写接口的一个或多个实现

  3. src/main/resources/META-INF/services/接口名文件, 内容是要应用的实现类

  4. 用 ServiceLoader 加载配置文件中指定的实现


主要被框架的开发人员使用,如 java.sql.Driver 接口,不同厂商可以针对同一接口做出不同的实现

场景

  Class.forName("com.mysql.jdbc.Driver") 

4.0 利用 SPI 直接

    String url = "jdbc:xxxx://xxxx:xxxx/xxxx";
    Connection conn = DriverManager.getConnection(url,username,password);

JDK SPI缺点/dubbo增强和优化

  1. JDK SPI 一次性实例化扩展点所有实现,没用上的耗时/耗资源也实例化

  2. 扩展点加载失败,连扩展点的名称都拿不到

    JDK ScriptEngine,getName(),如果依赖的 jruby.jar不存在,RubyScriptEngine实现类加载失败,失败原因被吃掉

    用户执行ruby脚本时,会报不支持ruby,而不是真正失败的原因

  3. 扩展点IoC和AOP支持,一个扩展点可setter注入其它扩展点

DUBBO SPI

META-INF/dubbo/接口

内容为:配置名=扩展实现类,多个实现类换行符分隔

配置文件是放在自己的jar包内,不是dubbo本身的jar包内,Dubbo会全ClassPath扫描


SPI 本地化扩展

与ServiceLoader 的 SPI 稍有不同,要打包成 jar 包后,放 jre/lib/ext

CalendarData/CalendarName/CurrencyName/LocaleName/LocaleService/ResourceBundleControl/TimeZoneName Provider