Hessian源码浅析-HessianProxy

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

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

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

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

Proxy是由HessianProxyFactory创建

HessianProxyFactory的create方法

	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方法主要向服务端发送请求 反序列化服务端返回的结果

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

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();
		}
	}



posted on 2012-05-12 21:56  YangJin  阅读(525)  评论(0编辑  收藏  举报