Dubbo原理实现之代理接口的定义
Dubbo有很多的实现采用了代码模式,Dubbo由代理工厂ProxyFactory对象创建代理对象。
ProxyFactory接口的定义如下:
@SPI("javassist")
public interface ProxyFactory {
/**
* create proxy.
*
* @param invoker
* @return proxy
*/
@Adaptive({Constants.PROXY_KEY})
<T> T getProxy(Invoker<T> invoker) throws RpcException;
/**
* create invoker.
*
* @param <T>
* @param proxy
* @param type
* @param url
* @return invoker
*/
@Adaptive({Constants.PROXY_KEY})
<T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) throws RpcException;
}
@SPI指定默认使用javassist字节码技术来生成代理对象,接口定义了生成代理对象的方法getProxy, 入参是invoker对象,接口定义了获取invoker对象, invoker对象是个可执行对象,这里inovker对象的invoke方法其实执行的是根据url获取的方法对第一个入参的实体对象的调用,即:如果url的得知调用方法sayHello, 入参proxy为空Test对象实现test,那invoker.invoke()就是test.sayHello()。
代理工厂的实现类图如下:
AbstractProxyFactory: 代理工厂的公共抽象, 这里抽象实现主要是获取需要代理的接口,代理接口可以在设置在url中,key为interfaces, 如果是多个接口用逗号分隔, 如果没有在url中指定,获取invoke接口和EchoService接口
public <T> T getProxy(Invoker<T> invoker) throws RpcException {
Class<?>[] interfaces = null;
String config = invoker.getUrl().getParameter("interfaces");
if (config != null && config.length() > ) {
String[] types = Constants.COMMA_SPLIT_PATTERN.split(config);
if (types != null && types.length > ) {
interfaces = new Class<?>[types.length + ];
interfaces[] = invoker.getInterface();
interfaces[] = EchoService.class;
for (int i = ; i < types.length; i++) {
interfaces[i + ] = ReflectUtils.forName(types[i]);
}
}
}
if (interfaces == null) {
interfaces = new Class<?>[]{invoker.getInterface(), EchoService.class};
}
return getProxy(invoker, interfaces);
}
JdkProxyFactory: 利用jdk动态代理来创建代理,实现比较简单
public <T> T getProxy(Invoker<T> invoker, Class<?>[] interfaces) {
return (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), interfaces, new InvokerInvocationHandler(invoker));
}
InvokerInvocationHandler是jdk动态代理创建一定要构建的参数,这里它的invoke方法只是简单的调用了invoker.invoke方法, Invoker在dubbo中代表一个可执行体,一切都向它靠拢。
获取invoker对象
public <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) {
return new AbstractProxyInvoker<T>(proxy, type, url) {
@Override
protected Object doInvoke(T proxy, String methodName,
Class<?>[] parameterTypes,
Object[] arguments) throws Throwable {
Method method = proxy.getClass().getMethod(methodName, parameterTypes);
return method.invoke(proxy, arguments);
}
};
}
这里创建的 Invoker对象,执行invoke方法,其实就是利用反射技术结合入参执行对应对象的对应方法。
Dubbo原理实现之代理接口的定义的更多相关文章
- 4. Dubbo原理解析-代理之接口定义 (转)
转载自 斩秋的专栏 http://blog.csdn.net/quhongwei_zhanqiu/article/details/41577159 一:ProxyFactory的接口定义 impo ...
- Spring只定义接口自动代理接口实现类
能够扫描到包 @ComponentScan("org.zxp.esclientrhl") ESCRegistrar类主要实现ImportBeanDefinitionRegistra ...
- Dubbo原理和源码解析之服务引用
一.框架设计 在官方<Dubbo 开发指南>框架设计部分,给出了引用服务时序图: 另外,在官方<Dubbo 用户指南>集群容错部分,给出了服务引用的各功能组件关系图: 本文将根 ...
- DUBBO原理、应用与面经总结
研读dubbo源码已经有一段时间了,dubbo中有非常多优秀的设计模式和示例代码值得学习,但是dubbo的调用层级和方法链都较为繁杂,如果不对源码思路进行梳理则很容易忘却,因此总结一篇研读心得,从阅读 ...
- Java进阶专题(二十六) 将近2万字的Dubbo原理解析,彻底搞懂dubbo
前言 前面我们研究了RPC的原理,市面上有很多基于RPC思想实现的框架,比如有Dubbo.今天就从Dubbo的SPI机制.服务注册与发现源码及网络通信过程去深入剖析下Dubbo. Dubbo架构 ...
- Java进阶专题(二十七) 将近2万字的Dubbo原理解析,彻底搞懂dubbo (下)
...接上文 服务发现 服务发现流程 整体duubo的服务消费原理 Dubbo 框架做服务消费也分为两大部分 , 第一步通过持有远程服务实例生成Invoker,这个Invoker 在客户端是核心的远程 ...
- Dubbo原理解析(非常透彻)
一.概述 dubbo是一款经典的rpc框架,用来远程调用服务的. dubbo的作用: 面向接口的远程方法调用 智能容错和负载均衡 服务自动注册和发现. 自定义序列化协议 Dubbo 架构中的核心角色有 ...
- Hibernate学习--hibernate延迟加载原理(动态代理)
在正式说hibernate延迟加载时,先说说一个比较奇怪的现象吧:hibernate中,在many-to-one时,如果我们设置了延迟加载,会发现我们在eclipse的调试框中查看one对应对象时,它 ...
- Dubbo原理和源码解析之“微内核+插件”机制
github新增仓库 "dubbo-read"(点此查看),集合所有<Dubbo原理和源码解析>系列文章,后续将继续补充该系列,同时将针对Dubbo所做的功能扩展也进行 ...
随机推荐
- Android Studio 老提示adb问题
Android Studio 老提示adb问题,restart后任然无解,最后发现某手机助手软件占用端口... 解决步骤: C:\Users\xxx>netstat -ano | findstr ...
- 统计方形(NOIP1997)
给链接:统计方形 这题是棋盘问题的数据加强版. 其实由于洛谷的数据比较水,所以你把我在棋盘问题题解中写的代码提交,也能AC. 但让给我们来看一个更优的解法. 先给代码: #include<bit ...
- kbmmw 的远程桌面功能
kbmmw 内置了远程桌面控制功能好几年了,好多同学居然不知道这特性,因为kbmmw 默认没有开放这个特性, 今天我就给大家说一下如何开放这个功能,并用官方自带例子说一下使用方法. 首先要开放这个特性 ...
- HierSort(希尔)————Java
利用Java进行希尔排序(元素中有0会有问题),步长经过调试length/2+1最合适. import java.util.Scanner; public class HierSort { priva ...
- Java 读取HDFS文件系统
最近有个需求,计算用户画像. 系统大概有800W的用户量,算每个用户的一些数据. 数据量比较大,算用hive还是毫无压力的,但是写的oracle,在给出数据给前端,就比较难受了. 然后换了种解决方法: ...
- jsp里面不能使用${pageContext.request.contextPath}解决方案
1.在jsp中使用${pageContext.request.contextPath}获取相对路径,可是最后路径变为:http://localhost:8080/oneself/$%7BpageCon ...
- Matlab编辑器背景修改
将下段代码如到C:\Users\Peng Chen\AppData\Roaming\MathWorks\MATLAB\R2016a\matlab.prf 先备份.prf,再替代之前的. #MATLAB ...
- 谈谈thinkphp5.1中容器(Container)和门面(Facade)的实现
tp5.1中引入了容器(Container)和门面(Facade)这两个新的类 官方文档已经给出了定义: 容器(Container)实现类的统一管理,确保对象实例的唯一性. 门面(Facade)为容器 ...
- location位置操作
使用location对象可以通过很多方式来改变浏览器的位置. location.assign('http://www.klkx.com') 传入一个URL地址 这样可以立即打开一个新的URL并在浏览器 ...
- Redis集群命令行部署工具
使用之前准备工作: 1)配置好与端口无关的公共redis.conf文件,和工具放在同一目录下 2)配置好与端口相关的模板redis-PORT.conf文件,也和工具放在同一目录下(部署时PORT会被替 ...