由Dubbo回声测试学到的
来源:互联网 发布:volatile java 优缺点 编辑:程序博客网 时间:2024/05/01 01:39
最近在看Dubbo的用户手册,看到了回声测试一小节的说明如下,请注意图片中的红框中的部分:
红色部分说:只需要将任意服务引用强制转换为EchoService,即可使用。
看到这里我想起了java中关于强制转换的一个限制:必须有继承关系,就是说两个类之间要能够进行类型转换,必须有继承关系才可以。 可是很明显,我们写的Dubbo服务接口是与EchoService接口没有任何集成关系的,这是如何实现的呢?
带着这个问题,去群里问了一下群主,群主给了如下截图:
1、
2、
3、
4、
可以看到,Dubbo在为我们写的服务创建动态代理的时候,是在传入的接口中人为的增加了“EchoService.class”接口的,也就是说,通过创建动态代理的时候向接口中增加一个接口,来保证强制转换的合法性。
这样就解决了强制转换的问题,但是又一个问题来了,EchoService接口中的方法是怎么实现的呢?因为我们写的接口是没有实现这个接口的,所以EchoService接口类中定义的方法也必然没有实现,虽然通过动态代理让我们的实现类实现了这个接口,但实际运行的时候还是会报错。
EchoService是这样定义的:
很奇怪的是,这里面的方法名字是写成了 $echo 的形式。
这个方法我们没有实现,那么如何保证在执行的时候能够执行呢?这是因为Dubbo提供了很多Filter,针对这个EchoService提供了一个EchoFilter实现:
可以看到,在方法里,直接判断当前执行的方法是不是$echo,如果是,则直接将参数返回,结束执行过程,否则继续执行后面的Filter。
为了验证一下,我也写了一点代码:
首先,也有一个EchoService接口,与Dubbo的一模一样。
public interface EchoService {Object $echo(Object message);}
然后自己定义了一个MyService接口和它的一个实现类MyServiceImpl。
接口类:
public interface MyService {public void sayHello();}
实现类:
public class MyServiceImpl implements MyService {@Overridepublic void sayHello() {System.out.println("MyServiceImpl:hello");}}
我要实现的功能是,将我的MyService实例对象转为EchoService对象 ,并调用其$echo方法。
运行代码如下:
public static void main(String[] args) {//首先定义一个MyService实例MyService myservice = new MyServiceImpl();//获取该实例所实现的接口Class<?>[] interfaces2 = myservice.getClass().getInterfaces();//将EchoService接口添加到Class<?>数组中Class<?>[] interfaces = new Class<?>[interfaces2.length + 1];interfaces[0] = EchoService.class;for (int i = 0; i < interfaces2.length; i++) {interfaces[i + 1] = interfaces2[i];}//创建代理对象Object obj = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), interfaces, new MyInvocationHandler(myservice));//正常调用MyService ms = (MyService) obj;ms.sayHello();//强制转为EchoServic对象并调用方法EchoService ec = (EchoService) obj;Object data = ec.$echo("aaaaa");System.out.println(data);}
注意,我实现了一个MyInvocationHandler:这个类是java动态代理必须的。
public class MyInvocationHandler implements InvocationHandler {private Object target;public MyInvocationHandler(Object target) {super();this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {System.out.println(method.getName());//处理EchoService方法,从而实现回声定位功能if(method.getName().equals("$echo")){return args[0];}return method.invoke(target, args);}}
运行一下,发现没有问题!
- 由Dubbo回声测试学到的
- dubbo——回声测试
- 由S_ISDIR学到的
- 12.dubbo回声测试、上下文信息、隐式参数
- 由CHandleMap::RemoveHandle异常学到的
- 由sqlmap学到的python杂烩
- 由NSObject学到的一点基本知识
- hsf dubbo学习六--泛化,回声测试,上下文信息,隐式传参,异步调用,本地调用
- 由一个程序异常终止问题学到的
- speex回声消除功能测试
- 回声客户端的实现
- 回声客户端的实现
- 学到的
- 学到的
- 我从华为身上学到的项目管理经验 -- 测试篇
- 测试自动化--学到的10课(血泪史)
- 由sort算法学到的配接与判断式法则的知识
- 由jdbc的入门程序学到的Java程序执行过程--class.forname()
- Keras深度学习框架学习笔记系列(2)- Keras的安装与配置
- python练习(十七)
- python 网页显示 json序列化中文乱码
- myeclipse中类下面的图标形状含义
- httpClient工具类
- 由Dubbo回声测试学到的
- 使用Angularjs和Vue.js对比
- Vue2.0 新手入门 — 从环境搭建到发布
- 正则表达式学习笔记
- mysql5.7的root密码强度
- 音频位深度、采样率以及码率
- maven优化依赖的三个命令和eclipse中图像化界面的对应关系
- java大数BigInteger总结
- JS:作用域以及作用域链