Hessian源码学习(2)

来源:互联网 发布:淘宝店被扣48分怎么办 编辑:程序博客网 时间:2024/06/11 16:29
我们在客户端是如何使用hessian呢? 
Java代码  收藏代码
  1. String url = "http://localhost:8080/Hello/hello";  
  2.   
  3. HessianProxyFactory factory = new HessianProxyFactory();  
  4.   
  5. // IHello为调用的服务接口,url为hessian服务url  
  6. IHello helloProxy = (IHello)factory.create(IHello.class, url);  
  7.   
  8. System.out.println(helloProxy.sayHello());  

以上代码就可以进行Hessian的远程调用了,但是这些究竟是怎么实现的呢,我们一步步分析(参考源码版本3.0.13)。 


factory.create(IHello.class, url); 

通过 HessianProxyFactory(Hessian代理工厂)创建一个代理类(采用JDK自带的动态代理),具体代码如下; 
Java代码  收藏代码
  1. public Object create(Class api, String urlName)  
  2.     throws MalformedURLException  
  3. {  
  4.     return create(api, urlName, Thread.currentThread().getContextClassLoader());  
  5. }  
  6.   
  7. public Object create(Class api, String urlName, ClassLoader loader)  
  8.     throws MalformedURLException  
  9. {  
  10.     URL url = new URL(urlName);  
  11.   
  12.     // HessianProxy implements InvocationHandler   
  13.     HessianProxy handler = new HessianProxy(this, url);    
  14.   
  15.     return Proxy.newProxyInstance(api.getClassLoader(),  
  16.                   new Class[] { api, HessianRemoteObject.class }, handler);  
  17. }  


helloProxy.sayHello(); 

实际上是调用代理类HessianProxy的invoke方法,我们具体看下代码: 
Java代码  收藏代码
  1. // 获取调用的方法名以及方法参数类型  
  2. String methodName = method.getName();  
  3. Class []params = method.getParameterTypes();  
  4.   
  5. //对于以下方法直接执行本地调用而不是远程调用  
  6. if (methodName.equals("equals") &&  
  7.     params.length == 1 && params[0].equals(Object.class)) {  
  8.     Object value = args[0];  
  9.     if (value == null || ! Proxy.isProxyClass(value.getClass()))  
  10.         return new Boolean(false);  
  11.   
  12.     HessianProxy handler = (HessianProxy) Proxy.getInvocationHandler(value);  
  13.     return new Boolean(_url.equals(handler.getURL()));  
  14.     }  
  15. else if (methodName.equals("hashCode") && params.length == 0)  
  16.   return new Integer(_url.hashCode());  
  17. else if (methodName.equals("getHessianType"))  
  18.   return proxy.getClass().getInterfaces()[0].getName();  
  19. else if (methodName.equals("getHessianURL"))  
  20.   return _url.toString();  
  21. else if (methodName.equals("toString") && params.length == 0)  
  22.   return "[HessianProxy " + _url + "]";  
  23.    
  24.   
  25. // 判断客户端是否要求支持重载(即客户端是否设置factory.setOverloadEnabled(true);   
  26. //注:3.0.13 只支持参数个数不同的重载,后面版本才真正意义上的支持重载)  
  27. if (! _factory.isOverloadEnabled()) {  
  28.     // 不要求重载,则什么都不做  
  29.     }  
  30. else if (args != null)  
  31.     // 若支持重载,则目标方法名格式为:method名 + "__" + method参数个数  
  32.     methodName = methodName + "__" + args.length;  
  33. else  
  34.     methodName = methodName + "__0";  
  35.      
  36. // 执行远程调用(建立http链接,设置一些http header, 序列化方法名和方法参数,执行http请求...)  
  37. conn = sendRequest(methodName, args);  
  38.   
  39. // 从输入流中读取远程调用结果并返回给客户端  
  40. is = conn.getInputStream();  
  41. AbstractHessianInput in = _factory.getHessianInput(is);  
  42. return in.readReply(method.getReturnType());  



0 0
原创粉丝点击