Java基礎:動態代理在RPC架構中應用

來源:互聯網
上載者:User

標籤:cep   代碼   cto   href   發送   bip   服務端   通過   proxy   

轉載請註明出處: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]);                         //建立InvocationHandlerCBIPInvocationHandlerhandler = 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架構返回調用結果;

Java基礎:動態代理在RPC架構中應用

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.