dubbo源码分析13——服务本地暴露 exportLocal(url)
dubbo服务的本地暴露,显然是针对当服务消费者和服务提供者都在同一个jvm的进程内这种场景 。通常是发生在服务之间的调用的情况下。一种情况就是A服务调用B服务的情况,如果A服务和B服务都是在一个线程中进行服务暴露的,就是本地调用。
下面先看本地暴露的源码:
private void exportLocal(URL url) {
//这是本协议url示例:injvm://127.0.0.1/org.huxin.dubbo.test.user.service.UserInterface?anyhost=true&application=dubbo-provider&default.retries=0&default.timeout=5000&dubbo=2.8.4&generic=false&interface=org.huxin.dubbo.test.user.service.UserInterface&methods=getUserById,getUserList,updateUsers&organization=huxin&owner=programmer&pid=5964&retries=0&serialization=kryo&side=provider×tamp=1513044127040
if (!Constants.LOCAL_PROTOCOL.equalsIgnoreCase(url.getProtocol())) {
URL local = URL.valueOf(url.toFullString())
.setProtocol(Constants.LOCAL_PROTOCOL)
.setHost(NetUtils.LOCALHOST)
.setPort(0); // ServiceClassHolder是用来保存当前服务接口实例ref对应的Class的,是一个简单的单例实现
ServiceClassHolder.getInstance().pushServiceClass(getServiceClass(ref));
//由于默认protocol是dubbo,所以此处的protocol应是com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol类的实例
Exporter<?> exporter = protocol.export(
proxyFactory.getInvoker(ref, (Class) interfaceClass, local));
exporters.add(exporter);
logger.info("Export dubbo service " + interfaceClass.getName() +" to local registry");
}
}
根据上面的源码,我们只需搞清楚Invoker实例是如何产生的,Invoker是什么,以及DubboProtocol的export方法就可以分析清楚本地暴露的过程了。
1. proxyFactory.getInvoker(ref, (Class) interfaceClass, local)
(1)首先是proxyFactory的来历
ServiceConfig类中初始化时进行实例化:private static final ProxyFactory proxyFactory = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
根据之前对dubbo的SPI机制,这个proxyFactory当是com.alibaba.dubbo.rpc.proxy.javassist.JavassistProxyFactory类的实例,也就是使用Javassist技术来产生Invoker对象。
ProxyFactory接口有两个方法:
<T> T getProxy(Invoker<T> invoker) throws RpcException; //供消费者使用
<T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) throws RpcException; //服务提供者使用
(2) JavassistProxyFactory实例的 getInvoker方法分析
可以通过如下源码看出Invoker实例在被调用时实隙地是通过其内部的wrapper对象调用proxy对象来完成的 ,下面分析下这个方法传入的参数:
- 第一个参数proxy传入是的ref变量 ,
ref的定义:private T ref; //接口实现类的引用 ,就是接口实现类的Class的实例
赋值的相关代码参见:http://www.cnblogs.com/hzhuxin/p/7677265.html
- 第二个参数 type 的定义是:private Class<?> interfaceClass; //也就是我们定义服务接口
- 第三个参数url 比较理解,是由之前面的调用方法 doExportUrlsFor1Protocol(protocolConfig, registryURLs) 方法拼接出来的
public <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) {
// TODO Wrapper类不能正确处理带$的类名
final Wrapper wrapper = Wrapper.getWrapper(proxy.getClass().getName().indexOf('$') < 0 ? proxy.getClass() : type);
return new AbstractProxyInvoker<T>(proxy, type, url) {
@Override
protected Object doInvoke(T proxy, String methodName,
Class<?>[] parameterTypes,
Object[] arguments) throws Throwable {
return wrapper.invokeMethod(proxy, methodName, parameterTypes, arguments);
}
};
}
2. DubboProtocol的export方法分析:
因本方法比较重要,新开一篇进行分析 ,参见http://www.cnblogs.com/hzhuxin/p/8228982.html
dubbo源码分析13——服务本地暴露 exportLocal(url)的更多相关文章
- 4. 源码分析---SOFARPC服务端暴露
服务端的示例 我们首先贴上我们的服务端的示例: public static void main(String[] args) { ServerConfig serverConfig = new Ser ...
- dubbo源码分析8——服务暴露概述
从上文中可知,com.alibaba.dubbo.config.spring.ServiceBean类是负责解析<dubbo:service/>的配置的,下面是它的类图 从类图上可知它继承 ...
- dubbo源码分析12——服务暴露3_doExportUrls()方法分析
本文紧接上文,doExportUrls()方法位于ServiceConfig类中,代码入口如下: private void doExportUrls() { List<URL> regis ...
- dubbo源码分析10——服务暴露1_export()方法分析
ServiceConfig类中的export()方法,是dubbo服务暴露的入口方法,被触发的时机有两个: 1. spring容器初始化完成所有的bean实例后,通过事件机制触发 2. 实现Initi ...
- dubbo源码分析11——服务暴露2_doExport()方法分析
protected synchronized void doExport() { //如果是已经解除暴露的接口则抛出异常 if (unexported) { throw new IllegalStat ...
- Dubbo源码分析系列---服务的发布
摘要: 通过解析配置文件,将xml定义的Bean解析并实例化,(涉及重要的类:ServiceBean.RegistryConfig[注册中心配置].ProtocolConfig[协议配置].Appli ...
- Dubbo 源码分析 - 服务导出
1.服务导出过程 本篇文章,我们来研究一下 Dubbo 导出服务的过程.Dubbo 服务导出过程始于 Spring 容器发布刷新事件,Dubbo 在接收到事件后,会立即执行服务导出逻辑.整个逻辑大致可 ...
- Dubbo 源码分析 - 服务调用过程
注: 本系列文章已捐赠给 Dubbo 社区,你也可以在 Dubbo 官方文档中阅读本系列文章. 1. 简介 在前面的文章中,我们分析了 Dubbo SPI.服务导出与引入.以及集群容错方面的代码.经过 ...
- dubbo源码分析2-reference bean发起服务方法调用
dubbo源码分析1-reference bean创建 dubbo源码分析2-reference bean发起服务方法调用 dubbo源码分析3-service bean的创建与发布 dubbo源码分 ...
随机推荐
- jenkins-ant-jmeter
jenkins下通过ant执行jmeter脚本 先下个ant 解压开来 在到jenkins中设置:系统管理-全局工具配置-ant安装-新增ant,填上name和ant-home 将jmeter的ant ...
- python中字符编码及unicode和utf-8区别
ascii和unicode是字符集,utf-8是编码集 字符集:为每一个「字符」分配一个唯一的 ID(学名为码位 / 码点 / Code Point) 编码规则:将「码位」转换为字节序列的规则(编码/ ...
- Storm常用的类
BaseRichSpout (消息生产者)BaseBasicBolt (消息处理者)TopologyBuilder (拓扑的构建器)Values (将数据存放到values ,发送到下个组件)Tupl ...
- windows批量修改文件后缀名
有时候需要批量修改一些文件的后缀名,下面介绍批量修改的方法. 1.在文件夹内新建一个.txt文本文档. 2.在文本文档内写:ren * *.mp3 (意思是把没有后缀名的全部改成.mp3的格式, ...
- bzoj千题计划314:bzoj3238: [Ahoi2013]差异(后缀数组+st表+单调栈)
https://www.lydsy.com/JudgeOnline/problem.php?id=3238 跟 bzoj3879 差不多 #include<cstdio> #include ...
- Retrofit的通讯方式示例
Retrofit有两种通讯方式,同步和异步 异步方式: APIService req; req = RetrofitManager.getInstance().createReq(APIService ...
- HTML 5 Web 本地存储
1.使用localStorage 2.使用sessionStorage 两者区别1关闭网页不失效,2失效.用法示例 localStorage.setItem(“key”,“value”)//存储 lo ...
- 31.【微服务架构】SpringCloud之Feign(五)
Feign简介 Feign 是一个声明web服务客户端,这便得编写web服务客户端更容易,使用Feign 创建一个接口并对它进行注解,它具有可插拔的注解支持包括Feign注解与JAX-RS注解,Fei ...
- 二叉搜索树BST
//遍历 void print(int p){ if(!p) return; print(left[p]); printf("%d\n",a[p]); print(right[p] ...
- l类与对象课后作业
java 的初始化规律 执行类成员定义时指定的默认值或类的初始化块,到底执行哪一个要看哪一个“排在前面”. 执行类的构造函数. 类的初始化块不接收任何的参数,而且只要一创建类的对象,它们就会被执行.因 ...