Dubbo---SPI机制源码解析
2021-08-29 16:02:37 0 举报
AI智能生成
登录查看完整内容
SPI流程和核心类解析
作者其他创作
大纲/内容
SPI (Service Provider Interface)。JDK设计的一种为某接口寻找服务实现机制。应用:1. jdbc定义接口,加载外部数据库驱动实现2. slfj 加载不同日志实现
定义
JDK SPI 通过ServiceLoader加载jar中的META-INF/services/路径下的SPI实现配置文件
Dubbo SPI 通过自定义的ExtensionLoader加载jar中META-INF/dubbo/接口全限定名的SPI实现配置问文件,配置内容为 配置名称 = 实现类的全限定类名
实现方式
JDK SPI 一次性实例化扩展点所有的实现。有可能加载应用没有用上的扩展实现类,造成资源的浪费。扩展点加载失败时报不支持的类型,不知道具体加载失败的扩展点。
Dubbo SPI 可以指定 扩展点的配置名称加载。提供了增强功能:①扩展点自动装配(IOC)②AOP的支持③扩展点的自适应
加载方式
dubbo SPI 和 JDK SPI区别
面向的角色不同框架通常有两类客户,一个是使用者,一个是扩展者。API是给使用者用的;SPI是给扩展者用的;
代码位置不同API通常是单独的jar包,只有接口的定义,没有接口的实现类SPI应用的实现jar包,配置依赖不同的实现类
API与SPI区别
SPI
使用自适应的原因
扩展点自适应
IOC功能
该类要实现 SPI 接口该类中要有 SPI 接口的引用该类中必须含有一个含参的构造方法且参数只能有一个类型为SPI接口在接口实现方法中要调用 SPI 接口引用对象的相应方法该类名称以 Wrapper 结尾
wrapper规范
AOP功能
标注一个接口是一个扩展点,可以被Dubbo的ExtensionLoader加载
@SPI
作用在类上,Dubbo源码中实现好的自适应扩展实现类,AdaptiveExtensionFactory和AdaptiveCompiler使用该注解
作用在方法上,表示是一个自适应方法,Dubbo在扩展点生成自适应实例时,会为该方法生成对应的代码,方法内部根据方法的参数,来决定使用哪个扩展
@Adaptive
扩展点自动激活,应用于集合类扩展点如Filter@Activate(\"xxx\"),当配置了xxx参数,并且参数值为有效值时激活@Activate(group=\"provider\
@Active
定义ExtensionLoader实例加载的扩展点(接口)类型private final Class<?> type;
定义扩展点实现IOC功能的工厂,Dubbo实现有的SpiExtensionFactory和SpringExtensionFactory,并且支持自适应适配private final ExtensionFactory objectFactory;
核心属性
私有化构造器,初始化时指定加载扩展的类型private ExtensionLoader(Class<?> type) { this.type = type; objectFactory =(type == ExtensionFactory.class ? null : ExtensionLoader.getExtensionLoader(ExtensionFactory.class).getAdaptiveExtension()); }
构造器
//获取扩展点的ExtensionLoader实例public static <T> ExtensionLoader<T> getExtensionLoader(Class<T> type)
//获取指定配置名称的扩展实现类public T getExtension(String name)
//没有从缓存中获取到,则创建一个实例private T createExtension(String name)
//扫描文件路径下的SPI扩展配置文件private void loadDirectory()
//读取配置文件实例化扩展点配置的CLass实例private void loadResource()
加载指定name的扩展点实例
//createExtension方法中初始化实例后调用InjectExtension方法通过setter方式注入依赖的属性private T injectExtension(T instance)
IOC自动装配功能实现
private Set<Class<?>> cachedWrapperClasses;//缓存wrapper Classtry { clazz.getConstructor(type); Set<Class<?>> wrappers = cachedWrapperClasses; if (wrappers == null) { cachedWrapperClasses = new ConcurrentHashSet<Class<?>>(); wrappers = cachedWrapperClasses; } wrappers.add(clazz);} catch (NoSuchMethodException e) {}
AOP功能warpper实现
//获取扩展点的自适应实例public T getAdaptiveExtension()
Dubbo实现的Adaptive扩展点有ExtensionFactory 和AdaptiveCompiler,其他的自适应实例都是通过拼接动态代码编译后生成的
//调用这个方法表明Dubbo的源码中没有实现当前扩展点的自适应实例,需要动态创建private T createAdaptiveExtension()
自适应扩展实例
ExtensionLoader
//初始化时在构造器中加载Dubbo配置所支持的ExtensionFactory扩展实例private final List<ExtensionFactory> factories;
//构造器中,初始化Dubbo支持的extensionFactory实例public AdaptiveExtensionFactory(){ ExtensionLoader<ExtensionFactory> loader = ExtensionLoader.getExtensionLoader(ExtensionFactory.class); List<ExtensionFactory> list = new ArrayList<>(); //加载项目配置支持的ExtensionFactory类 for (String extension : loader.getSupportedExtensions()) { ExtensionFactory factory = loader.getExtension(extension); list.add(factory); } factories = Collections.unmodifiableList(list); }
AdaptiveExtensionFactory
实现ExtensionLoader接口,使用Dubbo自定的ExtensionLoader加载指定name的扩展实现实例,这里返回的实例是一个Adaptive的实例,为了实现扩展点的自适应功能
SPIExtensionFactory
从Spring容器中加载指定name和Class对象的实例
SpringExtensionFactory
ExtensionFactory
把一个对象包装一下,使用volatile修饰 当前对象,保证关键对象的可见性
Holder<T>
Dubbo SPI核心类
SPI扩展机制
Dubbo
0 条评论
回复 删除
下一页