暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

再看Dubbo - Dubbo的SPI机制源码全解析

努力努力再努力xLg 2021-05-02
960

我准备战斗到最后,不是因为我勇敢,是我想见证一切。    --双雪涛《猎人》


  • 我准备战斗到最后,不是因为我勇敢,是我想见证一切。    --双雪涛《猎人》

  • 1、眼熟Dubbo的spi

  • 2、Dubbo的SPI源码详解

「Thinking」


  1. 一个技术,为什么要用它,解决了那些问题?
  2. 如果不用会怎么样,有没有其它的解决方法?
  3. 对比其它的解决方案,为什么最终选择了这种,都有何利弊?
  4. 你觉得项目中还有那些地方可以用到,如果用了会带来那些问题?
  5. 这些问题你又如何去解决的呢?

「本文基于Dubbo 2.7.5-SNAPSHOT」

Dubbo SPI架构图

Dubbo的SPI机制是Dubbo 整个架构中的核心,以它为基石来实现了Dubbo所有的功能都是以扩展点的形式进行可插拔操作的。

其解决了Java的SPI一次全部加载的弊端,也带来了更加灵活的应用。下面一起再来看看dubbo的SPI增强

Dubbo的SPI是以扩展点加载器去加载所有的实现类的jar。(在Dubbo的整个架构中,所有的功能模块都是一个maven项目,都是以jar包的形式集成的!)这也反向的说明了,Dubbo的SPI机制为什么依赖于扩展点加载器的原因了。

1、眼熟Dubbo的spi

        ExtensionLoader<Protocol> extensionLoader = ExtensionLoader.getExtensionLoader(Protocol.class);
Protocol protocol = extensionLoader.getExtension("http");
System.out.println(protocol);

返回值:org.apache.dubbo.rpc.protocol.ProtocolListenerWrapper@694e1548

留下一个疑问:这里为什么返回的是一个包装类呢?

/**
* person 的包装类
*
* @author by Mr. Li 2021/5/1 22:09
*/

public class PersonWrapper implements Person {

private Person person;

public PersonWrapper(Person person) {
this.person = person;
}

@Override
public Car getCar() {
Console.log("Wrapper");
return person.getCar();
}
}

添加类似的包装类,再在全限定名的问价那种添加该类的信息,dubbo的spi 并会返回该包装类

在ExtensionLoader类的内部有一个static的ConcurrentHashMap,用来缓存「某个接口类型所对应的ExtensionLoader实例」

ExtensionLoader
类中的javaDoc中就简单的说明了一下三点

  • auto inject dependency extension 类似于spring 的自动注入
  • auto wrap extension in wrapper 类似于aop
  • default extension is an adaptive instance

2、Dubbo的SPI源码详解

Dubbo的SPI机制

上图详细的跟踪了Dubbo的SPI加载

  • 为什么存在包装类时,返回的是一个包装类
  • Dubbo中使用双重检查锁时,为什么都使用的一个holder类来进行加锁
  • Dubbo的是如果兼容加载SPI文件的
  • Dubbo中是如果完美的使用Spring容器,或者自适应的方式生成代理类来实现IoC依赖注入的
  • Dubbo中的AOP具体实现
  • Dubbo中SPI中的SPI注解 Extension注解 adaptive注解的底层应用和实现

需要注意的一点,则是Dubbo中的每一个扩展类接口都对应着一个扩展类加载器

本文仅供笔者本人学习,一起进步!

加油!


文章转载自努力努力再努力xLg,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论