DubboSPI流程
2019-04-24 16:15:40 0 举报
DubboSPI流程
作者其他创作
大纲/内容
把接口默认的SPI的name放在缓存中缓存:private String cachedDefaultName;比如:Protocol接口的SPI注解为@SPI(\"dubbo\")则cachedDefaultName=dubbo
2.AOP对实例进行装饰
循环Filter的所有拓展类,共有18个根据参数key和group决定加载哪些Filter拓展类
ExtensionFactory objectFactory
依赖cachedWrapperClasses
getExtensionClasses()
缓存为空,加载拓展类
2.加载指定文件夹配置文件
加载自定义Filter
cacheDefaultExtensionName
1.因为public class Protocol$Adaptive目前只是个名字,在内存中还没有生成字节码,compile是从内存中找到字节码,所以调用compile异常2.如果异常,则调用doCompile方法生成 Protocol$Adaptive类的字节码因为里边有getExtension(\"dubbo\")的代码,所以会调用DubboProtocol的export的方法进行服务暴露
buildInvokerChain
3.编译代码,生成 Class
ProtocolFilterWrapper
1.获得自适应拓展类
getAdaptiveExtensionClass
loadClass
createAdaptiveExtension
以Protocol接口举例解释AOP
injectExtension
dubbo拓展机制三条线:1.获取自适应拓展实例 ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();2.获取拓展实例 ExtensionLoader.getExtensionLoader(Protocol.class).getExtension(\"dubbo\
静态属性
key校验
getExtensionClasses
#export
createAdaptiveExtensionClass
1.配置文件中service filter中配置的filter不包括AccessLogFilter 2.names中不包含\"-default\" 3.通过URL判断这个activate注解是激活的span style=\"font-size: inherit;\
getExtension(String name)
createAdaptiveExtensionClass 方法用于生成自适应拓展类,该方法首先会生成自适应拓展类的源码,然后通过 Compiler 实例(Dubbo 默认使用 javassist 作为编译器)编译源码,得到代理类 Class 实例
对象属性
1.获得拓展类
Dubbo AOP
1.所有接口的ExtensionLoader的objectFactory属性都为 AdaptiveExtensionFactory2.AdaptiveExtensionFactory会循环从SpiExtensionFactory和SpringExtensionFactory中寻找拓展类实例对原始的拓展类的属性进行注入3.SpiExtensionFactory其实还是执行getAdaptiveExtension寻找自适应拓展类,获得后进行注入
循环cachedActivates循环开始
3.Dubbo IOC注入依赖
getExtensionLoader(Class<T> type)
loadExtensionClasses
1.检查缓存cachedAdaptiveInstance中是否有 //自适应拓展实例 private final Holder<Object> cachedAdaptiveInstance = new Holder<>();2.缓存中没有,则调用createAdaptiveExtension创建自适 应拓展实例,然后把实例set到缓存中
loadDirectory
总体描述
1.loadClass类中会把该接口所有的装饰器类放入cachedWrapperClasses缓存中2.createExtension(String name)方法中,会循环cachedWrapperClasses缓存,然后利用装饰器的构造方法对拓展类进行装饰,然后返回装饰后新的实例3.所谓aop只是对单独的某个接口而言,会对该接口下所有的拓展类进行装饰,相对于对所有拓展类进行拦截,即AOP
getExtension(name);
包装了DubboProtocol
2.创建自适应拓展类
loadResource
2.获取编译器实现类
其实这里的实例是经过aop包装过的实例,调用的是ProtocolFilterWrapper的export的方法,然后才调用DubboProtocol的export方法
1.一个扩展点可以直接 setter 注入其它扩展点2.我们获得某个接口的某个拓展类的时候,如果实例的属性是另一个拓展类,此时它还是Null,我们需要注入它3.此时会从objectFactory中取到另一个拓展类的实例4.利用setXXX方法把3取到的实例set(注入)到拓展类的实例中
1.META-INF/services/ Java SPI 的配置目录(Dubbo SPI 对 Java SPI 做了兼容)2.META-INF/dubbo/ 用于用户自定义的拓展实现3.META-INF/dubbo/internal/ 用于 Dubbo 内部提供的拓展实现4.Pattern.compile(\
其实编译的是利用aop包装过的类
loadExtensionClasses 方法总共做了两件事情: 1. cacheDefaultExtensionName方法对接口默认 SPI 注解进行解析 2. 是调用 loadDirectory 方法加载指定文件夹配置文件
1.自动激活 适用于类上有@Acticve注解的类2.调用getExtensionClasses()加载所有类上有@Acticve注解 的类到cachedActivates缓存中3.利用group和key进行过滤4.加载自定义的Acticve类
SPI目录
构造过滤器链
2.Dubbo IOC注入依赖
1.通过 SPI 获取所有的拓展类 (1)getExtensionClasses正常会把自适应拓展类放到缓存中,这是真的类字节码 (2)如果缓存cachedAdaptiveClass中有则直接返回 (3)如果缓存没有则执行2创建自适应拓展类,这里是用javasist创建的字节码,不是原来的哪个了
createExtension(name)
加载AccessLogFilter这个拓展类的实例
exts.add(ext)循环结束
缓存为空,创建拓展实例
getAdaptiveExtension获取自适应拓展
dubbo默认使用JavassistCompiler
isMatchGroup
1.对接口默认 SPI 注解进行解析
ExtensionLoader
Compiler compiler = ExtensionLoader.getExtensionLoader(Compiler.class).getAdaptiveExtension()
获得所有过滤器
group和key校验都通过后,加入需要返回的拓展列表
1.构建自适应拓展代码
收藏
0 条评论
回复 删除
下一页