【客户端】
我们在客户端是如何使用hessian呢?
String url = "http://localhost:8080/Hello/hello";
HessianProxyFactory factory = new HessianProxyFactory();
IHello helloProxy = (IHello)factory.create(IHello.class, url);
System.out.println(helloProxy.sayHello());
以上代码就可以实现hessian的
远程调用了,但是这些究竟是怎么实现的呢,我们一步步分析。
factory.create(IHello.class, url); 通过 HessianProxyFactory(Hessian代理工厂)创建一个代理类,具体代码如下;
public Object create(Class api, String urlName)
throws MalformedURLException
{
return create(api, urlName, Thread.currentThread().getContextClassLoader());
}
public Object create(Class api, String urlName, ClassLoader loader)
throws MalformedURLException
{
URL url = new URL(urlName);
// HessianProxy implements InvocationHandler
HessianProxy handler = new HessianProxy(this, url);
return Proxy.newProxyInstance(api.getClassLoader(),
new Class[] { api, HessianRemoteObject.class }, handler);
}
helloProxy.sayHello(); 实际上是调用代理类的invoke方法,我们具体看下代码:
// 获取调用的方法名以及方法参数类型
String methodName = method.getName();
Class []params = method.getParameterTypes();
//对于以下方法直接执行本地调用而不是远程调用
if (methodName.equals("equals") &&
params.length == 1 && params[0].equals(Object.class)) {
Object value = args[0];
if (value == null || ! Proxy.isProxyClass(value.getClass()))
return new Boolean(false);
HessianProxy handler = (HessianProxy) Proxy.getInvocationHandler(value);
return new Boolean(_url.equals(handler.getURL()));
}
else if (methodName.equals("hashCode") && params.length == 0)
return new Integer(_url.hashCode());
else if (methodName.equals("getHessianType"))
return proxy.getClass().getInterfaces()[0].getName();
else if (methodName.equals("getHessianURL"))
return _url.toString();
else if (methodName.equals("toString") && params.length == 0)
return "[HessianProxy " + _url + "]";
// 判断客户端是否要求支持重载(即客户端是否设置factory.setOverloadEnabled(true);
//注:3.0.2 只支持参数个数不同的重载,后面版本才真正意义上的支持重载)
if (! _factory.isOverloadEnabled()) {
// 不要求重载,则什么都不做
}
else if (args != null)
methodName = methodName + "__" + args.length;
else
methodName = methodName + "__0";
// 执行远程调用(建立http链接,设置一些http header, 序列化方法名和方法参数,执行http请求...)
conn = sendRequest(methodName, args);
// 从输入流中读取远程调用结果并返回给客户端
is = conn.getInputStream();
AbstractHessianInput in = _factory.getHessianInput(is);
return in.readReply(method.getReturnType());
以上是客户端整个调用远程服务的流程(细节未涉及),总结:整个hessian远程调用可以用以下一副图概括:
- 大小: 29 KB