先来看咱们的provider.xml的配置文件spring
这个文件的重要性确定重要,那么这些标签是怎么来的呢?api
其实就是spring自定义标签来的,在源码中咱们能够看到,缓存
继续看spring.handlers文件中内容app
能够看得出这个DubboNamespaceHandler应该很重要,最后能够找出他的所在位置,同时还发现同目录下还有DubboBeanDefinitionParser相似于spring中BeanDefinitionParser。DubboNamespaceHandler相似于spring中NamespaceHandler:ide
再进去看看里面到底作了些什么东东函数
能够看到ui
DubboBeanDefinitionParser继承spring的BeanDefinitionParser,DubboNamespaceHandlerSupport继承spring的NamespaceHandlerSupport,NamespaceHandlerSupport继承NamespaceHandler。由此能够知道这个provider.xml配置文件的解析其实就是和spring同样解析。url
在这个spring目录下咱们看到这两个类spa
这两个类很是重要:debug
ServiceBean服务端发布入口
ReferenceBean客户端发布入口
先看看服务端的服务是怎么发布的
他是实现spring的这几类来作的。因此仍是基于spring来作的
这个类中afterPropertiesSet()方法中。是否延迟加载
export()方法就是作了一些参数校验
无论是否延迟加载都会走doExport()方法,doExport()方法也是作一些参数校验 和配置项的校验
而后调用doExportUrls()
就是在provider.xml中配置多个protocol
doExportUrlsFor1Protocol中 1:使用各类方法获取本地ip 2:若是没有配置端口则
final int defaultPort = ExtensionLoader.getExtensionLoader(Protocol.class).getExtension(name).getDefaultPort();
获取默认端口dubbo默认20880
3:拼凑url
dubbo://192.168.11.1:20880/com.tian.dubbo.IGpHello?anyhost=true&application=hello-world-app&default.delay=10&delay=10&dubbo=2.5.6&generic=false&interface=com.tian.dubbo.IGpHello&methods=sayHello&pid=121964&side=provider×tamp=1529758790987
而后
debug到此
这里有个Invoker对象为
因此咱们能够把Invoker对象理解为服务的代理对象。
若是没有配置注册中心,
protocol
----->Protocol$Adaptive
---->ProtocolFilterWrapper(ProtocolListenerWrapper(DubboProtocol))。底层是基于netty协议去启动一个nettyserver
} else {//若是没有配置注册中心 Invoker<?> invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass, url); Exporter<?> exporter = protocol.export(invoker);//dubbo exporters.add(exporter); }
Protocol extension = ExtensionLoader.getExtensionLoader(Protocol.class).getExtension(“registry”);
registry=com.alibaba.dubbo.registry.integration.RegistryProtocol
protocol=RegistryProtocol
RegistryProtocol的export方法源码
doLocalExport()本地发布
对缓存进行双重检查锁,若是有就直接返回,不然new一个
debug到此,相关属性对应的值:
exporter相关属性
此时相关值
上面
一样根据
Protocol extension =ExtensionLoader.getExtensionLoader(com.alibaba.dubbo.rpc.Protocol.class).getExtension(“dubbo”);
protocol=DubboProtocol.这里并非得到一个单纯的DubboProtocol扩展点,而是会经过Wrapper对Protocol进行装饰,装饰器分别为: ProtocolFilterWrapper/ ProtocolListenerWrapper;两个装饰类的源码为如下:
这个类很是重要,dubbo机制里面日志记录、超时等等功能都是在这一部分实现的
这个类有3个特色,
第一它有一个参数为Protocol protocol的构造函数;
第二,它实现了Protocol接口;
第三,它使用责任链模式,对export和refer函数进行了封装;部分代码以下,上面的源码中ProtocolFilterWrapper有个buildInvokderChain()方法
public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException { //buildInvokerChain函数:它读取全部的filter类,利用这些类封装invoker
|
咱们看以下文件:
/dubbo-rpc-api/src/main/resources/META-INF/dubbo/internal/com.alibaba.dubbo.rpc.Filter
其实就是对Invoker,经过以下的Filter组装成一个责任链
echo=com.alibaba.dubbo.rpc.filter.EchoFilter |
这其中涉及到不少功能,包括权限验证、异常、超时等等,固然能够预计计算调用时间等等应该也是在这其中的某个类实现的;这里其实就是dubbo中AOP
这里咱们能够看到export和refer过程都会被filter过滤
在这里咱们能够看到export和refer分别对应了不一样的Wrapper;export是对应的ListenerExporterWrapper。这块暂时先不去分析,由于这个地方并无提供实现类。
debug到此
exporterMap
createServer方法()
Exchangers.bind()方法
这里使用的是getExchange(url)=默认自适应扩展类HeaderExchanger
这里先去Transporters.bind()方法,
getTransporter().bind(url, handler);
这里的自适应扩展类就是默认的netty的
构造一个NettyServer
继续调用父类的方法
这个open()方法在这个父类里并无实现,而是采用模板方法模式,由各自实现类本身去实现
到此本地发布已经结束。