• Java基础:动态代理在RPC框架中应用


    转载请注明出处:jiq•钦's technical Blog 


    RPC。远端过程调用。就是调用远端机器上的方法。

    原理事实上非常easy。就是client上执行的程序在调用对象方法时,底层将针对该方法的调用转换为TCP/HTTP请求,发送到远端server,远端server监听固定port,收到这个TCP/HTTP请求后会解析出相关信息,包含client想要调用哪个类的哪个方法,參数是什么等,然后进行相应的调用,将调用结果再通过数据包发回就可以。

     

    RPC中通常会有一些“契约”的概念。即client和服务端两方约定好的接口,表明服务端实现了哪些接口,client能够使用这些接口。以下以一个我实现的简单的RPC框架为例说明。

     

    一、client

    client通常会创建一个服务訪问代理,事实上就是这个契约接口类型的对象,以下是一个创建服务代理的样例:

    //创建代理,调用服务
    IHelloService proxy= (IHelloService)RpcProxyFactory.createProxy(IHelloService.class,"HelloService", 3000);
    System.out.println("服务调用结果:"+proxy.sayHello("季义钦"));

     当中createProxy接口的实现例如以下:

    /**
     * 创建远程调用代理
     * @paramobjClass        接口类对象
     * @paramserviceName        服务名称
     * @paramURL        服务地址
     * @paramtimeout        连接超时时限
     * @return
     * @throws Exception
     */
    publicstatic Object createProxy(Class<?> objClass, String serviceName, StringURL, int timeout) throws Exception
    {
    //解析调用地址
    String[]urls = URL.split(":");
    StringipAddress = urls[1];
    intport =Integer.parseInt(urls[2]);                        
     
    //创建InvocationHandler
    CBIPInvocationHandlerhandler = new CBIPInvocationHandler(ipAddress, port, timeout);
    handler.setServiceName(serviceName);
     
    //返回代理
    returnProxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),new Class[]{objClass}, handler);
    }

     非常明显能够看到借助的是JavaInvocationHandler动态代理机制。通过Proxy静态方法newProxyInstance返回服务代理。


    当中CBIPInvocationHandler是client代码的核心。是实现了InvocationHandler接口的Java动态代理,其invoke方法实现例如以下:

    /**
     * 全部方法调用都通过invoke来运行
     */
    publicObject invoke(Object proxy, Method method, Object[] args) throws Throwable
    {
    Objectresult = null;
    try
    {
    //获取调用相关信息
    StringbeanName = this.serviceName; //this.targrtObject.getClass().getSimpleName();
    StringmethodName = method.getName();
    String[]argTypes = createParamSignature(method.getParameterTypes());
     
    //发起远程方法同步调用,传递调用信息
            result = invokeSync(beanName,methodName, argTypes, args);
    }
    catch(Exceptionee)
    {                
    ee.printStackTrace();
    returnnull;
    }
     
    returnresult;
    }

     invokeSync方法作用就是将调用相关信息通过Mina框架(JavaNIO框架,异步事件驱动,提供TCP/UDP通信的高层抽象API)发送出去。

     

    二、服务端

    通过Mina框架实现的服务端程序获取来自client的方法调用的请求数据包后。解析出调用相关信息。

    /**
         * 收到来自client的消息
         */
        @Override
        public void messageReceived(IoSessionsession, Object message) throws Exception {
           
               if(message instanceofCbipTcpRequest)
               {
                       CbipTcpRequestrequest = (CbipTcpRequest)message;
                       
                       
                       try
                       {
                               //读取spring配置文件依据服务名称获取服务全限定名,然后反射出目标实例
                       ApplicationContextctx = new ClassPathXmlApplicationContext("dsf_config.xml"); 
                       ServiceConfigservice = (ServiceConfig)ctx.getBean(request.getBeanName());
                       Class<?

    >objClass = Class.forName(service.getServiceName()); Objectobj = objClass.newInstance(); //调用指定的方法 CBIPSkeletonskeleton = new CBIPSkeleton(obj, obj.getClass()); Objectresult = skeleton.invoke(request.getMethodName(), request.getArgs()); //回复 CbipTcpResponse response= new CbipTcpResponse(); response.setRequestID(request.getId()); // 请求ID response.setBeanName(request.getBeanName()); response.setMethodName(request.getMethodName()); response.setResult(result); session.write(response); //相似套接字 }catch(Exceptionee) { ee.printStackTrace(); } } }


     这个数据包接收函数主要三个进行步骤:

    1)通过收到的client请求知道调用哪个类,从配置文件里读取该类的全限定名载入到JVM。反射出该类实例;

    2)通过反射出来的实例进行方法调用;

    3)通过Mina框架返回调用结果;

  • 相关阅读:
    超详细的sql2005图解安装全过程【图文】SQL Server 2005 安装图解(图文详解+全程截图)
    C# WinForm控件的拖动和缩放的实现
    C#中使用组合键事件,c#2005中组合键的应用
    C#判断Shift,Alt,Ctrl是否被按下,确定所按下的组合键
    详解破解VS2010正式版的方法(仅供技术交流)
    C# listview中显示imagelist中的图片
    序列化
    收集一些常用的正则表达式【转载】
    iframe+ajaxSubmit结合续篇(判断图片(文件)大小,上传图片,验证码刷新)
    完美去掉a标签和按钮加背景图片阴影
  • 原文地址:https://www.cnblogs.com/wgwyanfs/p/6814784.html
Copyright © 2020-2023  润新知