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(); } }
Andy_能力越到责任越大