Hessian客户端主要是通过proxy代理来实现 当客户端调用远程接口方法时 会被HessianProxy 代理 HessianProxy invoke方法主要做以下工作
1.把调用的 方法名称 参数 序列化
2.通过HttpURLConnection向服务端发送调用请求
3.服务端返回的结果 反序列化
Proxy是由HessianProxyFactory创建
HessianProxyFactory的create方法
- publicObjectcreate(Class<?>api,URLurl,ClassLoaderloader){
- if(api==null)
- thrownewNullPointerException(
- "apimustnotbenullforHessianProxyFactory.create()");
- InvocationHandlerhandler=null;
- //api远程接口
- handler=newHessianProxy(url,this,api);
- returnProxy.newProxyInstance(loader,newClass[]{api,HessianRemoteObject.class},handler);
- }
当调用远程接口的方法时 会激活HessianProxy代理的invoke方法 invoke方法主要向服务端发送请求 反序列化服务端返回的结果
- publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)
- throwsThrowable{
- StringmangleName;
- //从缓存中获取methodName
- synchronized(_mangleMap){
- mangleName=_mangleMap.get(method);
- }
- //如果缓存中没有
- if(mangleName==null){
- StringmethodName=method.getName();
- Class<?>[]params=method.getParameterTypes();
- //如果是equals,hashcode,getHessianType,getHessianURL
- //直接调用url的对应方法返回结果不会向服务端发送请求
- if(methodName.equals("equals")&¶ms.length==1
- &¶ms[0].equals(Object.class)){
- Objectvalue=args[0];
- if(value==null||!Proxy.isProxyClass(value.getClass()))
- returnBoolean.FALSE;
- ObjectproxyHandler=Proxy.getInvocationHandler(value);
- if(!(proxyHandlerinstanceofHessianProxy))
- returnBoolean.FALSE;
- HessianProxyhandler=(HessianProxy)proxyHandler;
- returnnewBoolean(_url.equals(handler.getURL()));
- }elseif(methodName.equals("hashCode")&¶ms.length==0)
- returnnewInteger(_url.hashCode());
- elseif(methodName.equals("getHessianType"))
- returnproxy.getClass().getInterfaces()[0].getName();
- elseif(methodName.equals("getHessianURL"))
- return_url.toString();
- elseif(methodName.equals("toString")&¶ms.length==0)
- return"HessianProxy["+_url+"]";
- //重载方法支持默认false
- if(!_factory.isOverloadEnabled())
- mangleName=method.getName();
- else
- //重载方法处理最终已methodName_参数类型_参数类型..形式返回
- mangleName=mangleName(method);
- //缓存起来
- synchronized(_mangleMap){
- _mangleMap.put(method,mangleName);
- }
- }
- InputStreamis=null;
- HessianConnectionconn=null;
- try{
- //序列化方法名称参数向服务端发出请求
- //mangleName方法定义可能是methodName_参数类型_参数类型..
- //args参数
- conn=sendRequest(mangleName,args);
- //获得HttpURLConnection的输入流
- is=conn.getInputStream();
- AbstractHessianInputin;
- intmajor=is.read();
- intminor=is.read();
- in=_factory.getHessianInput(is);
- in.startReplyBody();
- //反序列化服务端返回结果
- Objectvalue=in.readObject(method.getReturnType());
- if(valueinstanceofInputStream){
- value=newResultInputStream(conn,is,in,(InputStream)value);
- is=null;
- conn=null;
- }else
- in.completeReply();
- //返回最终结果
- returnvalue;
- }catch(HessianProtocolExceptione){
- thrownewHessianRuntimeException(e);
- }finally{
- //..略
- }
- }
sendRequest 方法主要序列化请求信息(方法,参数) 然后向服务端发送请求 HessianConnection包装了HttpURLConnection
- protectedHessianConnectionsendRequest(StringmethodName,Object[]args)
- throwsIOException{
- //包装了javaHttpURLConnection
- HessianConnectionconn=null;
- conn=_factory.getConnectionFactory().open(_url);
- booleanisValid=false;
- try{
- addRequestHeaders(conn);
- OutputStreamos=null;
- try{
- os=conn.getOutputStream();
- }catch(Exceptione){
- thrownewHessianRuntimeException(e);
- }
- AbstractHessianOutputout=_factory.getHessianOutput(os);
- //序列化
- out.call(methodName,args);
- out.flush();
- //发出网络请求
- conn.sendRequest();
- isValid=true;
- returnconn;
- }finally{
- if(!isValid&&conn!=null)
- conn.destroy();
- }
- }

本文转自:http://blog.youkuaiyun.com/java2000_wl/article/details/7560393
本文解析了Hessian客户端如何通过代理实现远程方法调用的过程,包括方法调用的序列化、发送请求及结果的反序列化等关键步骤。
798

被折叠的 条评论
为什么被折叠?



