java spi

JAVA SPI浅析

spi最典型的实例应用就是jdbc4.0,在jdbc4.0之前我们加载一个jdbc驱动通过Class.forName加载驱动,例子如下:

Class.forName("com.mysql.jdbc.Driver");  
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306"test", "root", "123456");  
Statement stmt = conn.createStatement();  
ResultSet rs = stmt.executeQuery("select * from Users");  

上面是jdbc4.0 加载驱动方式,Class.forName("com.mysql.jdbc.Driver");这里虽是加载mysql的driver,但是无论是oracle还是其它的jdbc驱动包,它们的原理都是spi机制。我们来看java.sql.Driver接口,这个接口在jdk中没有实现,这个接口是具体的个个数据厂商实现的.

Dubbo扩展点记载从JDK标准的SPI(Service Provider Interface)扩展点发现机制加强而来.

Dubbo改进了JDK标准SPI的几个问题 核心类(ExtensionLoader)

  • JDK标准的SPI会一次性实例化扩展点所有实例,如果扩展实现初始化很耗时,但是如果没有用上也会被加载,这是非常浪费资源的.
  • 如果扩展加载失败了,启动不会报错,而在使用时会报不支持错误,比如: JDK 标准的
    ScriptEngine,通过 getName() 获取脚本类型的名称,但如果RubyScriptEngine 因为所依赖的 jruby.jar 不存在,导致 RubyScriptEngine 类加载失败,这个失败原因被吃掉了,和 ruby 对应不起来,当用户执行 ruby脚本时,会报不支持ruby,而不是真正失败的原因。
  • 增加了对扩展点 IoC 和 AOP 的支持一个扩展点可以直接 setter 注入其它扩展点。