Hessian源码浅析-HessianProxy

 

Hessian客户端主要是通过proxy代理来实现 当客户端调用远程接口方法时 会被HessianProxy 代理  HessianProxy invoke方法主要做以下工作

1.把调用的 方法名称 参数 序列化

2.通过HttpURLConnection向服务端发送调用请求

3.服务端返回的结果 反序列化

Proxy是由HessianProxyFactory创建

HessianProxyFactory的create方法

  1. public Object create(Class<?> api, URL url, ClassLoader loader) {  
  2.     if (api == null)  
  3.         throw new NullPointerException(  
  4.                 "api must not be null for HessianProxyFactory.create()");  
  5.     InvocationHandler handler = null;  
  6.     //api  远程接口   
  7.     handler = new HessianProxy(url, this, api);  
  8.     return Proxy.newProxyInstance(loader, new Class[] { api, HessianRemoteObject.class }, handler);  
  9. }  
	public Object create(Class<?> api, URL url, ClassLoader loader) {
		if (api == null)
			throw new NullPointerException(
					"api must not be null for HessianProxyFactory.create()");
		InvocationHandler handler = null;
		//api  远程接口
		handler = new HessianProxy(url, this, api);
		return Proxy.newProxyInstance(loader, new Class[] { api, HessianRemoteObject.class }, handler);
	}

当调用远程接口的方法时 会激活HessianProxy代理的invoke方法 invoke方法主要向服务端发送请求 反序列化服务端返回的结果

  1. public Object invoke(Object proxy, Method method, Object[] args)  
  2.             throws Throwable {  
  3.         String mangleName;  
  4.         // 从缓存中获取methodName   
  5.         synchronized (_mangleMap) {  
  6.             mangleName = _mangleMap.get(method);  
  7.         }  
  8.         // 如果缓存中没有   
  9.         if (mangleName == null) {  
  10.             String methodName = method.getName();  
  11.             Class<?>[] params = method.getParameterTypes();  
  12.             //如果是 equals, hashcode ,getHessianType,getHessianURL    
  13.             //直接调用url的对应方法返回结果   不会向服务端发送请求   
  14.             if (methodName.equals("equals") && params.length == 1  
  15.                     && params[0].equals(Object.class)) {  
  16.                 Object value = args[0];  
  17.                 if (value == null || !Proxy.isProxyClass(value.getClass()))  
  18.                     return Boolean.FALSE;  
  19.                 Object proxyHandler = Proxy.getInvocationHandler(value);  
  20.                 if (!(proxyHandler instanceof HessianProxy))  
  21.                     return Boolean.FALSE;  
  22.                 HessianProxy handler = (HessianProxy) proxyHandler;  
  23.                 return new Boolean(_url.equals(handler.getURL()));  
  24.             } else if (methodName.equals("hashCode") && params.length == 0)  
  25.                 return new Integer(_url.hashCode());  
  26.             else if (methodName.equals("getHessianType"))  
  27.                 return proxy.getClass().getInterfaces()[0].getName();  
  28.             else if (methodName.equals("getHessianURL"))  
  29.                 return _url.toString();  
  30.             else if (methodName.equals("toString") && params.length == 0)  
  31.                 return "HessianProxy[" + _url + "]";  
  32.             //重载方法支持 默认false   
  33.             if (!_factory.isOverloadEnabled())  
  34.                 mangleName = method.getName();  
  35.             else  
  36.                 //重载方法处理  最终已  methodName_参数类型_参数类型..形式返回   
  37.                 mangleName = mangleName(method);  
  38.             //缓存起来   
  39.             synchronized (_mangleMap) {  
  40.                 _mangleMap.put(method, mangleName);  
  41.             }  
  42.         }  
  43.         InputStream is = null;  
  44.         HessianConnection conn = null;  
  45.         try {  
  46.             //序列化 方法名称  参数  向服务端发出请求     
  47.             //mangleName 方法定义 可能是methodName_参数类型_参数类型..    
  48.             //args 参数   
  49.             conn = sendRequest(mangleName, args);  
  50.             //获得HttpURLConnection 的输入流   
  51.             is = conn.getInputStream();  
  52.             AbstractHessianInput in;  
  53.             int major = is.read();  
  54.             int minor = is.read();  
  55.             in = _factory.getHessianInput(is);  
  56.             in.startReplyBody();  
  57.             //反序列化服务端返回结果    
  58.             Object value = in.readObject(method.getReturnType());  
  59.             if (value instanceof InputStream) {  
  60.                 value = new ResultInputStream(conn, is, in, (InputStream) value);  
  61.                 is = null;  
  62.                 conn = null;  
  63.             } else  
  64.                 in.completeReply();  
  65.             //返回最终结果   
  66.             return value;  
  67.         } catch (HessianProtocolException e) {  
  68.             throw new HessianRuntimeException(e);  
  69.         } finally {  
  70.         //..略   
  71.         }  
  72.     }  
public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		String mangleName;
		// 从缓存中获取methodName
		synchronized (_mangleMap) {
			mangleName = _mangleMap.get(method);
		}
		// 如果缓存中没有
		if (mangleName == null) {
			String methodName = method.getName();
			Class<?>[] params = method.getParameterTypes();
			//如果是 equals, hashcode ,getHessianType,getHessianURL 
			//直接调用url的对应方法返回结果   不会向服务端发送请求
			if (methodName.equals("equals") && params.length == 1
					&& params[0].equals(Object.class)) {
				Object value = args[0];
				if (value == null || !Proxy.isProxyClass(value.getClass()))
					return Boolean.FALSE;
				Object proxyHandler = Proxy.getInvocationHandler(value);
				if (!(proxyHandler instanceof HessianProxy))
					return Boolean.FALSE;
				HessianProxy handler = (HessianProxy) proxyHandler;
				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 + "]";
			//重载方法支持 默认false
			if (!_factory.isOverloadEnabled())
				mangleName = method.getName();
			else
				//重载方法处理  最终已  methodName_参数类型_参数类型..形式返回
				mangleName = mangleName(method);
			//缓存起来
			synchronized (_mangleMap) {
				_mangleMap.put(method, mangleName);
			}
		}
		InputStream is = null;
		HessianConnection conn = null;
		try {
			//序列化 方法名称  参数  向服务端发出请求  
			//mangleName 方法定义 可能是methodName_参数类型_参数类型.. 
			//args 参数
			conn = sendRequest(mangleName, args);
			//获得HttpURLConnection 的输入流
			is = conn.getInputStream();
			AbstractHessianInput in;
			int major = is.read();
			int minor = is.read();
			in = _factory.getHessianInput(is);
			in.startReplyBody();
			//反序列化服务端返回结果 
			Object value = in.readObject(method.getReturnType());
			if (value instanceof InputStream) {
				value = new ResultInputStream(conn, is, in, (InputStream) value);
				is = null;
				conn = null;
			} else
				in.completeReply();
			//返回最终结果
			return value;
		} catch (HessianProtocolException e) {
			throw new HessianRuntimeException(e);
		} finally {
		//..略
		}
	}

sendRequest 方法主要序列化请求信息(方法,参数) 然后向服务端发送请求  HessianConnection包装了HttpURLConnection

  1. protected HessianConnection sendRequest(String methodName, Object[] args)  
  2.             throws IOException {  
  3.         //包装了java HttpURLConnection   
  4.         HessianConnection conn = null;  
  5.         conn = _factory.getConnectionFactory().open(_url);  
  6.         boolean isValid = false;  
  7.   
  8.         try {  
  9.             addRequestHeaders(conn);  
  10.             OutputStream os = null;  
  11.             try {  
  12.                 os = conn.getOutputStream();  
  13.             } catch (Exception e) {  
  14.                 throw new HessianRuntimeException(e);  
  15.             }  
  16.             AbstractHessianOutput out = _factory.getHessianOutput(os);  
  17.             //序列化   
  18.             out.call(methodName, args);  
  19.             out.flush();  
  20.             //发出网络请求   
  21.             conn.sendRequest();  
  22.             isValid = true;  
  23.             return conn;  
  24.         } finally {  
  25.             if (!isValid && conn != null)  
  26.                 conn.destroy();  
  27.         }  
  28.     }  
protected HessianConnection sendRequest(String methodName, Object[] args)
			throws IOException {
		//包装了java HttpURLConnection
		HessianConnection conn = null;
		conn = _factory.getConnectionFactory().open(_url);
		boolean isValid = false;

		try {
			addRequestHeaders(conn);
			OutputStream os = null;
			try {
				os = conn.getOutputStream();
			} catch (Exception e) {
				throw new HessianRuntimeException(e);
			}
			AbstractHessianOutput out = _factory.getHessianOutput(os);
			//序列化
			out.call(methodName, args);
			out.flush();
			//发出网络请求
			conn.sendRequest();
			isValid = true;
			return conn;
		} finally {
			if (!isValid && conn != null)
				conn.destroy();
		}
	}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值