码迷,mamicode.com
首页 > 其他好文 > 详细

由Dubbo回声测试学到的

时间:2015-05-27 16:10:42      阅读:336      评论:0      收藏:0      [点我收藏+]

标签:

最近在看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 {
@Override
public 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;
}
@Override
public 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回声测试学到的

标签:

原文地址:http://my.oschina.net/jasonultimate/blog/420580

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!