图2.
图3.
这些dubbo 节点的 service 是通过 META-INF 下的spring.handlers文件下DubboNameSpaceHandler类 ,把service节点封装成
serviceBean类。其他的节点类似。xml的节点解析成对应的类型。bean初始化。
图4
图5
serviceBean 类 实现Spring 的接口.重写onApplicationEvent() 监听的方法,和afterPropertiesSet()方法。并且是后者早于前者执行。
图6.
图7
图1中。
1.首先图3 中,provider的加载要早于 service.从加载中获取provider
2.如果加载中没有获取到为null ,直接从spring中获取图
3.获取完后setProviders进去。
图8
图8 onApplicationEvent 方法 是监控spring 启动时触发的事件。真正的入口方法 export();
图9
图9的checkAndUpdateSubConfigs() ;检查和更新什么呢。配置来源于外部配置和内部配置。比如 在dubbo控制台做的更新属于外部。在
图10
provider的刷新 。从xml中解析的的providerConfig 类赋值给provider对象。
图11
图11.从545获取外部provider的配置信息(包括system->控制台应用配置->控制台全局配置->perpties配置文件)。
548行到554 默认的配置是: system->配置中心app->配置中心全局->properties 如果是配置中心优先则为 system->配置中心app->配置中心全局->bean初始化值(xml)->properties ;如果不是system->->bean初始化值(xml)->配置中心app->配置中心全局->properties
557行到566行 获取providerConfig类型的set 方法,遍历赋值,然后反射调用赋值。
561行,从configList中获取值(外部配置信息);
图12
图12中获取外部配置的顺序为. System -> 应用配置->管理台全局配置-->配置文件中获取. 获取完信息后放在一个configList中configList 是一个LinekedList<>的集合,严格保证了顺序。
图13
图14
图14从配置启动项中获取配置信息。
图15
图15 启动项配置在一个propertis文件中。从配置文件中直接获取。
图16
图17
图17 从properties 中获取。和上面的启动项获取类似。唯一不一样的是通过CofigUtils工具类读取配置文件。
图18
图18 177行,为什么又有从系统System中读取呢,是不是混合读呢? 其实这是dubbo为了保证System的最高优先级。如果能够从System中读到则直接返回。
图19
图19获取配置文件 路径信息, 根据路径加载配置文件。
图20
图20 。是获取控制台的应用配置信息,和全局配置信息。然后从map 取出信息放在configuration中返回。问题来了。这个map 什么时候放进去值呢? 一起看看吧。
从zookeeper中获取配置信息(zookeeper中的配置信息来自于dubbo控制台中的,全局配置和应用配置)。
图21
图21为 重写spring 的afterPropertiesSet()方法中调用init() .
82行到92行 从zookeeper中的dubbo/config/dubbo/dubbo.properties 中获取配置信息.
95行到96行 获取的配置信息更新到map中。
图22
图22 从zookeeper中获取的配置信息url,根据配置信息url加载对应的配置文件 ,遍历配置文件,并放入map中。返回。
图23
图23 把封装好的map 更新到最终的map中去。
图24
图24 说明具体 从zookeeper中加载的文件的位置。
图25
图25 111 行 获取 providerCofig类中获取get方法并截取方法名(除去get 前缀的,首字母大写)作为属性名称。 并把获取的属性名和值放入map中返回。判断address是否为空。为空放默认的。 获取协议,如果协议为空默认设置为zookeeper.。并把map解析成url返回。
图26
图26 利用dubbo的spi技术 获取DynamicCofigurationFactory的实现类 ,url.getPortocol() 返回的是zookeeper 。所以他的实现类是 ZookeeperDynamicConfigurationFactionFactory .
图27
图27调用getDynamicConfigurantion(url)方法。 此方法有调用 ZookeeperDynamicConfigurantionFactory 的 createDynamicConfiguration(url);
图28
图28,29 中从Zookeeper实现类中返回的,cofigurantion中包含,图29的信息包含 url,rootPath等重要信息。
图30
图31
图32
图30,31,32,封装zookeeper对应的路径信息 dubbo/config/dubbo/dubbo/dubbo.properties 到 configuration 中去并返回。getConfig() 是有图21的83行调用。
图33
图33 标识的zookeeper中对应的路径。
图34
图35
图36
图 34,35,36 获取providerConfig 类的 get方法。去掉get前缀,首字母 大写的方法名做为属性名返回。
图37
图37 默认的配置是: system->配置中心app->配置中心全局->properties 如果是配置中心优先则为 system->配置中心app->配置中心全局->bean初始化值(xml)->properties ;如果不是system->->bean初始化值(xml)->配置中心app->配置中心全局->properties
图38
图39
图39 从cofigLisit中按顺序获取值,
图40
图40 真正的导出。 判断是否已经导出过。导出过返回。对服务引用和全类名进行包装成ProviderMode类
图41
图42
图42进行协议导出。407行 加载注册中心。 408 多个协议遍历,每个协议。409行 每个协议遍历多个注册中心。也就是一个应用对应多个协议,对应多个注册中心。
图43
图43 说明多个协议
图44
图44 registry url 详情
图45
图45 246行遍历多个注册中心。 把application信息,path,address,protocol等信息放在一个map,然后用map转化成一个url。
如果是提供者 并且他的url 是注册,获取他不是提供者他的url参数包括订阅则,则放在registryList中返回。
图46
图46 详细说明了 服务提供者在zookeeper 中注册的详细路径,
图47
图47 详细说明了服务提供者在zookeeper中注册的详细信息。
服务导出的 主要几步; 1.解析 url ,2 注册服务提供者的监听事件,3,启动服务器(tomcat,jetty) ,4 .,在zookeeper 的节点下创建 临时节点,节点信息存储url详细信息。
图48
图48 把相关的xlm 的节点(节点解析为对象)封装成map ,来完成了内部配置的属性覆盖。
图49
图49 对method方法进行处理。
图50
图50 493行工具类,获取可提供服务者的 方法名。
图51
图51 500 行到506行, token处理。即在控制中心放置一个token ,服务消费者在调用提供者时,携带token 去提供者验证。507行判断是否本地协议,如果是 不注册,不通知。
图52
图52 519行将map转换成url
图53
图53. scope属性是否有值,如果没有值,则远程和本地同时暴露。如果不是远程暴露本地。如果不是本地暴露远程。
图54
图54 557行 调用invoker 执行体, 在registryUrl _后面添加 export = 服务提供者的url 构建新的url。 558 行封装 warpperInvoke. 560行,protocol 导出,protocol的实现类,从invoker 的 getUrl() 方法,获取。
图55
图55是服务提供者的url详细信息。
图56
图56 工具类型获取所有的方法名字。
图57
图57 本地方法暴露。 首先不是远程的 设置协议为 injvm ,设置端口为0 ,protocol.exprot()方法暴露和远程一致。
图58
图58是 registry的Url 添加 服务url后的详细信息。
图59
图59获取Protocol协议的动态生成实现类。
图60
图60 接口的实现类从url确定,没有url从invoker的getUrl中获取url 。然后通过url.getProtocol方法获取 protocol的实现类名称。
图61
图61 为 获取得到protocol的实现类为registry实现类型。
图62
图62确定实现类型为 registryProtocol类
图63
图63 registryProtocol的exprot()方法。 170 行方法获取registryUrl 并且 把协议registry 换成 zookeeper ,172 获取服务提供者的url
178行到180行,给服务提供者绑定监听事件(当监控中心 服务提供者发生变化,例如有人从控制中心配置timeout ,能够及时通知提供者), 184行 启动 服务器(Tomcat,jeety) ,
图64
图64 187行 获取注册中心。 188修改url信息。 193行196行开始注册。
图65
图65获取providerUrl的方法。
图66
图66获取registryUrl的方法。 286行到289行 添加url添加registry=zookeeper
图67
图68
图69
图70
图71
图69至图71 为为服务提供者绑定监听事件。
图72
图72 281 行根据url 获取Registry的实现类为zookeeper 实现类型。
图73
图73 194行开始注册。
图74
图74 dubbo2.7 如果配置 registryUrl 配置简单的服务提供者则移除 监控信息等相关信息减少zookeeper的数据压力。 返回要提供者的url
图75
图75 把处理好的注册中心Url 和处理好的服务提供者url 传参开始注册。194行
图76 根据registry的url确定注册中心的实现类型为zookeeper.
图77
图78
图78 112 行,zk创建临时节点完成注册。
图79
图79 注册地址的在zookeeper中详细路径。dubbo/configurators/providers下。
图80
图81
图81 启动服务器(根据xml配置,图80 ,配置tomcat 启动tomcat,配置 jetty启动jetty)
图82
图82 216行 从缓存获取提供者的url信息。 224行 获取包装类 也就是 dubbo的aop类。依次需要执行 实现了protocol接口的实现类 protocolListenerWrapper ,proocolFilterapper,httpProtocol类。
图83
图83实现了protocol接口的类。
图84
图85
图86
图86 ProtocolListenerWrapper->ProtocolFilterWrapper->httpProtocol 执行各自的 exporter方法为类的执行顺序。
图87
图87 54行 如果是注册的协议,直接返回,
57行 通过dubbo的spi技术获取ExporterListener实现类 ,对一些监听事件进行处理。可以自定义实现这个监听类暴露服务后触发一些事件。
图88
图88 执行完ProtocolListenerWrapper 的export方法紧接着执行 ProtocolFilterWrapper类的exproter()方法。
图89
图89 循环处理监听事件。
图90
图90 73行执行下一个invoke ,递归调用下一个invoke方法,最终返回一个invoke.
图91
图91 执行完protocolFilterWrapper 紧接着执行 HttpProtocol 的export方法,但是HttpProtocol没有export方法,执行父类的export方法。
71行 执行通过invoker获取url 的 实现类为HttpProtocol的实现的doExport方法。
图92
图 92获取HttpProtocol实现类的方法。
图93
图93 77行从配置文件xml获取 服务相关地址。 80行绑定url和对应处理的handler. 从url中获取tomat服务器帮顶。
图94
图94设置请求方式,远程地址和端口。
图95
图95获取tomcat实现类型。
图96
图96启动tomcat
图97
图97创建 提供者的访问地址路径,并且存在map中
图98
图98创建对应的service存入类型,和实现。
图99
图100
图99 图100 用创建好的代理类来处理 调用 service
图101
图101 从map中获取路径和地址,封装到request,response中。
图102
图102 处理请求。
图103
图103 封装请求的方法名,参数类型,属性等值。
图104
图104 通过代理类反射调用。
图105
图105反射调用
图106 本地暴露和本地引用。
图106 暴露的时候exproterMap 放入 InjvmExporter,
图107
图107 取得时候从exporterMap中 取出值。
图108
本地暴露
图109
图109从url中获取exporter对象返回。
总结图: