SPI

SPI

SPI:Service Provider Interface,是JDK内置的一种服务提供机制。许多开发框架都使用了JavaSPI机制,如java.sql.DriverSPI实现(mysql驱动、oracle驱动等common-logging的日志接口实现、dubbo的扩展实现等等。

面向的对象的设计里,我们一般推荐模块之间基于接口编程,模块之间不对实现类进行硬编码。一旦代码里涉及具体的实现类,就违反了可拔插的原则,如果需要替换一种实现,就需要修改代码。在实际过程中,API的实现是封装在jar包中的,所以当需要更换一种实现时,要生成新的jar包来替换以前的类。为了实现在模块装配的时候不用在程序里动态指明,这就需要一种服务发现机制。java spi就是提供这样的一个机制:为某个接口寻找服务实现的机制。通过它就可以实现,不修改原来jar的情况下,为api新增一种实现。这有点类似IOC的思想,将装配的控制权移到了程序之外。

SPI缺陷

ServiceLoader缺少一些有用的特性:

  • 缺少实例的维护ServiceLoader每次load后,都会生成一份实例,也就是我们理解的prototype

  • 无法获取指定的实例,在Spring中可以通过beanFactory.getBean(“id”)获取一个实例,但是ServiceLoader不支持,只能一次获取所有的接口实例;

  • 不支持排序ServiceLoader返回的接口实例没有进行排序,随着新的实例加入,会出现排序不稳定的情况;

  • 无法获的所有实现的类型 无法通过接口获取所有的接口实例类型;

  • 作用域缺失,没有定义singletonprototype的定义,不利于用户进行自由定制。

Links