探究Dubbo的ExtensionLoader

一定要对比JDK的SPI机制,才能更好的理解Dubbo的SPI实现!

扩展点:即接口
扩展:扩展点的实现,即接口的实现类
  1. 获取扩展点的ServiceLoader实例

  2. 通过扩展点的ServiceLoader实例,完成扩展的方法调用

package com.nucc;
​
import java.util.ServiceLoader;
​
/**
 * JDK SPI Sample.
 */
public class App {
    public static void main(String[] args) {
        ServiceLoader<Command> serviceLoader = ServiceLoader.load(Command.class);
​
        for (Command cmd : serviceLoader) {
            cmd.execute();
        }
    }
}

通过以上代码理解了JDK的SPI机制,那么DUBBO SPI机制该怎么实现?

1⃣ 获取扩展点的ExtensionLoader实例,希望它是单例的,初始化后将它缓存起来(方便以后拿出来直接用);

2⃣ 获取扩展的实例,为了避免JDK SPI中一次全部加载带来的资源损耗问题,Dubbo SPI机制应在设计上应采用延迟加载机制,即只获取想要的扩展,而非将全部扩展进行加载。

深入探究Dubbo的ExtensionLoader

  1. getExtensionLoader(Class<?> type) : 单例模式,获取接口type的ExtensionLoader实例,扩展上必须添加@SPI注解,对于扩展点只会加载一次,生成一个ExtensionLoader实例,放入缓存中。

  2. getAdaptiveExtension() :获取扩展点的实现,dubbo框架在调用getAdaptiveExtension()中,将配置文件中的META-INF\dubbo\internal下所有的配置初始化加载到缓存中,这个方法会首先在扩展点接口的所有实现类中查找类上是否含有@Adaptive注解,如果有这个样的类注解返回该类的实例,如果没有则会查找扩展点接口的方法是否有@Adaptive注解,并动态编译一个类实现该接口并扩展这些含有@Adaptive注解的方法。默认将采用@SPI注解value指定的扩展。如果开发者选择使用其它扩展,则在dubbo的spring xml配置中指定。Dubbo使用“自适应”的扩展,在运行时通过URL中的配置参数决定采用哪一个扩展的方案,解决了JDK SPI中一次全部加载带来的资源损耗问题。

    如果用@Adaptive标记一个类,表示该类是一个自适应的扩展点实现,目前系统只有两个:AdaptiveCompiler(整个框架仅支持Javassist和JdkCompiler)和AdaptiveExtensionFactory(整个框架仅支持2个objFactory,一个是spi,另一个是spring);

    如果用@Adaptive标记一个方法,则dubbo会动态生成一个扩展点的实现,例如Protocol$Adaptive(dubbo的动态代码生成与编译),该扩展点代码实现是通过javassit技术动态创建的类,并由dubbo编译加载。

    --> 面向对象设计的“开闭原则”,以及动态代理模式

    在上述流程中,生成一个扩展点的实例(适配器类)时,需要完成依赖的注入,Dubbo采用ExtensionFactory扩展点的实现来完成(SPI和Spring),即采用injectExtension方法为适配器的setter方法插入其它扩展点的实现或者Spring中的bean,此处为dubbo的Ioc设计。

  3. getExtension(String name) : 获取指定名字的扩展

转载于:https://my.oschina.net/maliang1989/blog/1941627

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值