标签:ebe EDA 注解 image 源码解析 透明 rect load 机制
1.0 源码解读见dubbo官网:http://dubbo.apache.org/zh-cn/docs/source_code_guide/dubbo-spi.html
1.1 SPI 全称为 Service Provider Interface,是一种服务发现机制。SPI 的本质是将接口实现类的全限定名配置在文件中,并由服务加载器读取配置文件,加载实现类。
1.2总结:javaspi需要创建所有的实现类,且无法指定具体的实现类
1.3 Dubbo spi创建过程:
接口用@SPI标示,在META-INF/dubbo下创建名称是接口限定名的文件,文件用键值对便是,key自定义,value是实现累的限定名。
1.4 Dubbo源码流程:
l 首先通过 ExtensionLoader 的 getExtensionLoader 方法获取一个 ExtensionLoader 实例, getExtensionLoader 方法用于从缓存中获取与拓展类对应的 ExtensionLoader,若缓存未命中,则创建一个新的实例。
l 然后再通过 ExtensionLoader 的 getExtension 方法获取拓展类对象。这其中,检查缓存,缓存未命中则调用createExtension 方法创建拓展对象。
l createExtension 方法包含了如下的步骤:
1) 通过 getExtensionClasses 获取该SPI标示的接口type文件夹下所有的拓展类,(先从缓存中读取没有就通过配置的文件读取)再获取指定的拓展类
2) 通过反射创建该拓展对象
3) 向拓展对象中注入依赖(springioc,遍历目标类的所有方法,获取setter方法通过反射实现依赖注入)
4) 将拓展对象包裹在相应的 Wrapper 对象中,返回该实例(通过装饰实现springaop)
有时,有些拓展并不想在框架启动阶段被加载,而是希望在拓展方法被调用时,根据运行时参数进行加载。自适应拓展机制的实现逻辑比较复杂,首先 Dubbo 会为拓展接口生成具有代理功能的代码。,所有扩展点都通过传递 URL 携带配置信息。然后通过 javassist 或 jdk 编译这段代码,得到 Class 类。最后再通过反射创建代理类。
创建自适应拓展类步骤:
l getAdaptiveExtension 方法是获取自适应拓展的入口方法,首先会检查缓存,缓存未命中就创建。
l createAdaptiveExtension 方法,
1) 调用 getAdaptiveExtensionClass 方法获取自适应拓展 Class 对象,
2) 再通过反射进行实例化,
3) 然后调用 injectExtension 方法向拓展实例中注入依赖
l getAdaptiveExtensionClass 方法
l createAdaptiveExtensionClass:该方法首先会生成自适应拓展类的源码,然后通过 Compiler 实例(Dubbo 默认使用 javassist 作为编译器)编译源码,得到代理类 Class 实例。接下来,我们把重点放在代理类代码生成的逻辑上
生成拓展加载与目标方法调用逻辑,
比如
com.alibaba.dubbo.rpc.Protocol extension = (com.alibaba.dubbo.rpc.Protocol) ExtensionLoader
.getExtensionLoader(com.alibaba.dubbo.rpc.Protocol.class).getExtension(extName);
return extension.refer(arg0, arg1);
(1)容器创建完之后会触发ServiceBean(实现了applicationLIstener接口)类中的ContextRefreshedEvent事件,执行export()方法。
(2)export()方法会调用ServiceConfig中的doExport()方法,这个方法会调用doExportUrls()方法,进而doExportUrlsFor1Protocol()方法。
(3)doExportUrlsFor1Protocol()方法中会利用反射构造invoker,这个invoker封装了服务实现类注册的地址及端口相关信息。同时执行protocol.export()方法。
(4)protocol.export()中的protocol有两个实现类,这个是最关键的,一个是RegistryProtocol一个是DubboProtocol,调用这个方法的时候会首先调用RegistryProtocol类,RegistryProtocol类中的export()方法会调用doLocalExport()方法通知DubboProtocol执行openServer(url)方法进行服务的开启,其实就是开启一个netty服务。同时export()方法会调用ProviderConsumerRegTable.registerProvider()方法进行注册表的缓存以及服务的注册。
在ReferenceBean->getObject()->init()中会调用createProxy()方法用来创建代理对象。
在createProxy()中会执行一个refprotocol.refer()方法,这里refprotocol同样有两个实现类,一个是RegistryProtocol,一个是DubboProtocol
RegistryProtocol负责注册信息,订阅信息,构造invoker代理类,并将消费者对于的invoke缓存到注册列表中。
DubboProtocol主要负责connect/getClients()连接获取客户端,等待与服务端通信
dubbo服务调用源码流程
dubbo框架可以分为10层,而这10层又可以归为Business、RPC、Remoting这三层。
Business
Service业务层:业务代码的接口和实现。我们实际使用的Dubbo的业务层级。该层是与实际业务逻辑相关的,根据服务提供方和服务消费方的业务设计对应的接口和实现。
RPC
Config配置层: 对外的配置接口,以ServiceConfig和ReferenceConfig为中心,可以直接new配置类,也可以通过spring解析配置生成配置类。主要是dubbo的一些配置。
Proxy服务代理层:服务接口透明代理,生成服务的客户端 Stub 和服务器端 Skeleton, 扩展接口为ProxyFactory 。不论是Consumer还是Provider,Dubbo都会对其生成代理,在代理之间进行通信。
Registry注册中心层:封装服务地址的注册与发现,以服务 URL 为中心,扩展接口为 RegistryFactory, Registry, RegistryService。进行服务的注册与发现。
Cluster路由层:封装多个Provider的路由以及负载均衡,并桥接注册中心,以 Invoker 为中心,扩展接口为 Cluster, Directory, Router, LoadBalance。就是将多个服务组合起来形成一个大服务。
Monitor监控层:RPC 调用次数和调用时间监控,以 Statistics 为中心,扩展接口为 MonitorFactory, Monitor, MonitorService。
Remoting
protocol 远程调用层:封装 RPC 调用,以 Invocation, Result 为中心,扩展接口为 Protocol, Invoker, Exporter。
exchange 信息交换层:封装请求响应模式,同步转异步,以 Request, Response 为中心,扩展接口为 Exchanger, ExchangeChannel, ExchangeClient, ExchangeServer。
transport 网络传输层:抽象 mina 和 netty 为统一接口,以 Message 为中心,扩展接口为 Channel, Transporter, Client, Server, Codec。
serialize 数据序列化层:可复用的一些工具,扩展接口为 Serialization, ObjectInput, ObjectOutput, ThreadPool。
标签:ebe EDA 注解 image 源码解析 透明 rect load 机制
原文地址:https://www.cnblogs.com/zhouyanger/p/13266654.html