Dubbo的SPI的分析

首先定义:

SPI:即Service Provider Interface,释义为服务提供接口

JDK SPI:Java的spi机制,是去扫描/META-INF/service/的接口名文件,并获取文件中的值。以mysql的驱动类来做为案例。

打开对应文件:

ServiceLoader<Command> serviceLoader=ServiceLoader.load(Command.class); 
for(Command command:serviceLoader){ 
   // 循环执行
   command.execute();  
}  

这里用到了类的上下文加载器进行加载。
Java通过迭代器,循环加载对应文件中的类。

dubbo SPI:
通过ExtensionLoader.getExtension(String name)实现路径:

getExtensionLoader(Class<T> type) 就是为该接口 new 一个 ExtensionLoader,然后缓存起来。



getAdaptiveExtension() 获取一个扩展类,如果 @Adaptive 注解在类上就是一个装饰类;如果注解在方法上就是一个动态代理类,例如 Protocol$Adaptive 对象。



getExtension(String name) 获取一个指定对象。
public static <T> ExtensionLoader<T> getExtensionLoader(Class<T> type) {
    // 删除部分非空判断代码// 先判断扩展类是否已经存在
    ExtensionLoader<T> loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type);
    if (loader == null) 
        // 缓存 interface 对应的 dubbo spi 扩展加载类
        EXTENSION_LOADERS.putIfAbsent(type, new ExtensionLoader<T>(type));
        loader = (ExtensionLoader<T>) EXTENSION_LOADERS.get(type);
    }
    return loader;
}private ExtensionLoader(Class<?> type) {
        this.type = type;
    // 创建工厂,即 dubbo 的 IOC 输出中心,两个实现类 [SpiExtensionFactory,SpringExtensionFactory]
        objectFactory = (type == ExtensionFactory.class ? null : ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension());
    }

 

public T getExtension(String name) {
    // 删除部分代码
    // 获取一个实体类,其中持有一个 volatile 的 interface 实现类对象,保证内存可见性
    Holder<Object> holder = cachedInstances.get(name);
    if (holder == null) {
        cachedInstances.putIfAbsent(name, new Holder<Object>());
        holder = cachedInstances.get(name);
    }
    Object instance = holder.get();
    if (instance == null) {
        synchronized (holder) {
            instance = holder.get();
            if (instance == null) {
             // 创建一个 interface 的实例对象
                instance = createExtension(name);
                holder.set(instance);
            }
        }
    }
    return (T) instance;
}private T createExtension(String name) {
      // 获取对应的 name 的 class 加载类
        Class<?> clazz = getExtensionClasses().get(name);
      // 省略部分代码
        try {
            // 缓存对应是否存在
            T instance = (T) EXTENSION_INSTANCES.get(clazz);
            if (instance == null) {
                EXTENSION_INSTANCES.putIfAbsent(clazz, (T) clazz.newInstance());
                instance = (T) EXTENSION_INSTANCES.get(clazz);
            }
            // 注入对象
            injectExtension(instance);
            Set<Class<?>> wrapperClasses = cachedWrapperClasses;
            if (wrapperClasses != null && wrapperClasses.size() > 0) {
                for (Class<?> wrapperClass : wrapperClasses) {
                    // 构造器注入,,,IOC 
                    instance = injectExtension((T)  wrapperClass.getConstructor(type).newInstance(instance));
                }
            }
            return instance;
        } catch (Throwable t) {
            // 异常处理
        }
    }private T injectExtension(T instance) {
 try {
  if (objectFactory != null) {
   for (Method method : instance.getClass().getMethods()) {
     // 获取方法名是 set 的属性,进下属性注入,,即 IOC 
                if (method.getName().startsWith("set")
      && method.getParameterTypes().length == 1
      && Modifier.isPublic(method.getModifiers())) {
     Class<?> pt = method.getParameterTypes()[0];
     try {
      String property = method.getName().length() > 3 ? method.getName().substring(3, 4).toLowerCase() + method.getName().substring(4) : "";
      Object object = objectFactory.getExtension(pt, property);
      if (object != null) {
       method.invoke(instance, object);
      }
     } catch (Exception e) {
      logger.error("fail to inject via method " + method.getName()
        + " of interface " + type.getName() + ": " + e.getMessage(), e);
     }
    }
   }
  }
 } catch (Exception e) {
  logger.error(e.getMessage(), e);
 }
 return instance;
}

ExtensionLoader.getExtensionLoader(Class type)#

 ExtensionLoader.getExtensionLoader(Container.class) -->this.type = type; -->objectFactory = (type == ExtensionFactory.class ? null : ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension()); -->ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension() -->this.type = type; -->objectFactory =null;

getExtension(String name) 核心调用链如下#
getExtension(String name)
//指定对象缓存在cachedInstances;get出来的对象wrapper对象,例如protocol就ProtocolFilterWrapper和ProtocolListenerWrapper其中一个。

 -->createExtension(String name) -->getExtensionClasses() -->injectExtension(T instance)//dubbo的IOC反转控制,就是从spi和spring里面提取对象赋值。 -->objectFactory.getExtension(pt, property) -->SpiExtensionFactory.getExtension(type, name) -->ExtensionLoader.getExtensionLoader(type) -->loader.getAdaptiveExtension() -->SpringExtensionFactory.getExtension(type, name) -->context.getBean(name) -->injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance))//AOP的简单设计

getAdaptiveExtension()#

   -->getAdaptiveExtension()//为cachedAdaptiveInstance赋值 -->createAdaptiveExtension() -->getAdaptiveExtensionClass() -->getExtensionClasses()//为cachedClasses 赋值 -->loadExtensionClasses() -->loadFile -->createAdaptiveExtensionClass()//自动生成和编译一个动态的adpative类,这个类是一个代理类 -->ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.common.compiler.Compiler.class).getAdaptiveExtension() -->compiler.compile(code, classLoader) -->injectExtension()//作用:进入IOC的反转控制模式,实现了动态注入

总结

  • 1、dubbo 设计了一系列缓存,jdk spi 不支持缓存;

    2、dubbo 设计了默认初始化的类,jdk spi 不支持;

    3、dubbo 动态获取 SPI 对象,jdk spi 需进行 for 循环判断;

    4、dubbo 设计了 AOP 功能,XxxxFilterWrapper XxxxListenerWrapper;

    5、dubbo 设计了 IOC 功能,wrapperClass.getConstructor(type).newInstance(instance):

猜你喜欢

转载自blog.csdn.net/damokelisijian866/article/details/102810939
今日推荐