先說一下rpc 的調用過程
客戶端:知道接口名和方法名,以及參數類型、調用參數的值 ,但是本地並沒有該接口的實現
服務端:這裏有接口的實現
調用時,客戶端使用JDK動態代理,利用接口創建了一個代理對象
創建代理對象需要兩個東西:
1、一個就是接口的全限定名(包名+接口名),
2、還需要一個調用處理接口 InvocationHandler 的實現
說明:每次使用代理對象調用方法時,其實調用的是 InvocationHandler 接口的實現中的invoke 方法
invoke 方法中的實現了遠程調用:
1、根據服務端的IP 和端口號,創建一個socketServer ,
2、將接口全限定名、方法名、參數類型、參數值、通過socket 傳遞到服務端
3、服務端根據接口名獲得接口的實現類的實例對象,使用反射調用該方法,得到執行結果
4、將執行結果寫入socket ,傳遞給客戶端
5、客戶端得到結果返回結果
這裏是invoke代碼
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
// 把調用服務所需的信息封裝到bean中
InvokerBean invokerBean = new InvokerBean(name, new RPCMethod(method.getName(), method.getParameterTypes()),
args);
// 啓動socket
Socket client = new Socket(address, port);
// 把序列化對象轉換成流,使用JDK自帶的ObjectOutputStream
ObjectOutputStream oos = new ObjectOutputStream(client.getOutputStream());
oos.writeObject(invokerBean);
oos.flush();
// 讀取服務端返回的結果
ObjectInputStream ois = new ObjectInputStream(client.getInputStream());
invokerBean = (InvokerBean) ois.readObject();
oos.close();
ois.close();
client.close();
return invokerBean.getResult();
}
整個過程就是rpc 的基本實現原理