java spi与dubbo spi区别

java spi与dubbo spi区别

java spi :是上游产商给服务供应商提供的接口,供应商遵循接口契约提供自己的实现.。提供了服务接口的一种实现之后,在jar包的META-INF/services/目录里同时创建一个以服务接口命名的文件。该文件里就是实现该服务接口的具体实现类。而当外部程序装配这个模块的时候,就能通过该jar包META-INF/services/里的配置文件找到具体的实现类名,并装载实例化,完成模块的注入。 基于这样一个约定就能很好的找到服务接口的实现类,而不需要再代码里制定。简单来讲就是为某个接口寻找服务实现的机制。

package search;  

import java.util.Iterator;  
import java.util.ServiceLoader;  

public class SearchTest {  

    public static void main(String[] args) {  
        ServiceLoader<Search> s = ServiceLoader.load(Search.class);  
        Iterator<Search> searchs = s.iterator();  
        if (searchs.hasNext()) {  
            Search curSearch = searchs.next();  
            curSearch.search("test");  
        }  
    }  
}  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

dubbo spi : Dubbo的扩展点加载从JDK标准的SPI(Service Provider Interface)扩展点发现机制加强而来。 
当接口上打了该注解时,dubbo会在META-INF/dubbo/internal/接口全名文件下读取扩展点.配置文件内容为name->implementation class,可以声明多个提供者. 
SPI组件在dubbo称为ExtensionLoader–扩展容器 
1.Extension 扩展点 
2.Wrapper 包装类 
3.Activate 激活点 
4.Adaptive 代理 
Adaptive的决策过程,最终还是会通过容器获得当次调用的扩展点来完成调用: 
- 取得扩展点的key 
1. Adaptive方法必须保证方法参数中有一个参数是URL类型或存在能返回URL对象的方法,容器通过反射探测并自动获取。 
2. key默认是接口类型上的@SPI#value,方法上的@Adaptive#value有更高的优先级。 
3. 如果2都为空则以interface class#simpleName为key, key生成规则:”AbcAbcAbc”=>”abc.abc.abc” 
- 如果key值是protocol,则直接调用URL#getProtocol方法获取扩展点名称,如果不是则使用URL#getMethodParameter(key)或getParameter(key),其返回值作为扩展点名称,这里的URL是在步骤1获得的 
- 通过ExtensionFactory获取扩展点。ExtensionFactory用于获取指定名称的扩展点,它最终还是通过容器的getExtension去获取或生成。如果用户声明的provider里有wrapper,则返回的是被包装过的实体对象。 
两个区别:

  1. dubbo spi 可以通过getExtension(String key)的方法方便的获取某一个想要的扩展实现,java的SPI机制需要加载全部的实现类。
  2. 对于扩展实现IOC依赖注入功能,如现在实现者A1含有setB()方法,会自动注入一个接口B的实现者,此时会注入一个动态生成的接口B的实现者B$Adpative

猜你喜欢

转载自blog.csdn.net/liao1990/article/details/80633079