日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

Java在远程方法调用中运用反射机制

發(fā)布時(shí)間:2025/3/12 java 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java在远程方法调用中运用反射机制 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

我們將介紹反射機(jī)制在網(wǎng)絡(luò)編程中的應(yīng)用,實(shí)現(xiàn)如何在客戶端通過遠(yuǎn)程方法調(diào)用服務(wù)器端的方法。

假定在服務(wù)器端有一個(gè) HelloService 接口,該接口具有 getTime() 和 echo() 方法,具體代碼如下:

import java.util.Date;public interface HelloService {public String echo(String msg);public Date getTime(); }

在服務(wù)器上創(chuàng)建一個(gè) HelloServiceImpl 類并實(shí)現(xiàn) HelloService 接口。HelloServiceImpl 類的代碼如下:

import java.util.Date;public class HelloServiceImpl implements HelloService {@Overridepublic String echo(String msg) {return "echo:" + msg;}@Overridepublic Date getTime() {return new Date();} }

上述代碼所示,在 HelloServiceImpl 類中對(duì) echo() 方法和 getTime() 方法進(jìn)行了重寫。那么,客戶端如何調(diào)用服務(wù)器端 Hello-ServiceImpl 類中的 getTime() 和 echo() 方法呢?

具體方法是:客戶端需要把調(diào)用的方法名、方法參數(shù)類型、方法參數(shù)值,以及方法所屬的類名或接口名發(fā)送給服務(wù)器端。服務(wù)器端再調(diào)用相關(guān)對(duì)象的方法,然后把方法的返回值發(fā)送給客戶端。

為了便于按照面向?qū)ο蟮姆绞絹硖幚砜蛻舳伺c服務(wù)器端的通信,可以把它們發(fā)送的信息用 Call 類來表示。一個(gè) Call 對(duì)象表示客戶端發(fā)起的一個(gè)遠(yuǎn)程調(diào)用,它包括調(diào)用的類名或接口名、方法名、方法參數(shù)類型、方法參數(shù)值和方法執(zhí)行結(jié)果。

Call 類的實(shí)現(xiàn)代碼如下:

import java.io.Serializable;public class Call implements Serializable {private static final long serialVersionUID = 6659953547331194808L;private String className; // 表示類名或接口名private String methodName; // 表示方法名private Class[] paramTypes; // 表示方法參數(shù)類型private Object[] params; // 表示方法參數(shù)值// 表示方法的執(zhí)行結(jié)果// 如果方法正常執(zhí)行,則result為方法返回值,如果方法拋出異常,那么result為該異常。private Object result;public Call() {}public Call(String className, String methodName, Class[] paramTypes, Object[] params) {this.className = className;this.methodName = methodName;this.paramTypes = paramTypes;this.params = params;}public String getClassName() {return className;}public void setClassName(String className) {this.className = className;}public String getMethodName() {return methodName;}public void setMethodName(String methodName) {this.methodName = methodName;}public Class[] getParamTypes() {return paramTypes;}public void setParamTypes(Class[] paramTypes) {this.paramTypes = paramTypes;}public Object[] getParams() {return params;}public void setParams(Object[] params) {this.params = params;}public Object getResult() {return result;}public void setResult(Object result) {this.result = result;}public String toString() {return "className=" + className + "methodName=" + methodName;} }

假設(shè)客戶端為 SimpleClient,服務(wù)器端為 SimpleServer。SimpleClient 調(diào)用 SimpleServer 的 HelloServiceImpl 對(duì)象中 echo() 方法的流程如下:

1 . SimpleClient 創(chuàng)建一個(gè) Call 對(duì)象,它包含調(diào)用 HelloService 接口的 echo() 方法的信息。

2 . SimpleClient 通過對(duì)象輸出流把 Call 對(duì)象發(fā)送給 SimpleServer。

3 . SimpleServer 通過對(duì)象輸入流讀取 Call 對(duì)象,運(yùn)用反射機(jī)制調(diào)用 HelloServiceImpl 對(duì)象的 echo() 方法,把 echo() 方法的執(zhí)行結(jié)果保存到 Call 對(duì)象中。

4 . SimpleServer 通過對(duì)象輸出流把包含方法執(zhí)行結(jié)果的 Call 對(duì)象發(fā)送給 SimpleClient。

5 . SimpleClient 通過對(duì)象輸入流讀取 Call 對(duì)象,從中獲得方法執(zhí)行結(jié)果。

首先來看看客戶端程序 SimpleClient 類的實(shí)現(xiàn)代碼。

import java.io.*; import java.net.*; import java.util.*; import java.lang.reflect.*; import java.io.*; import java.net.*; import java.util.*;public class SimpleClient {public void invoke() throws Exception {Socket socket = new Socket("localhost", 8000);OutputStream out = socket.getOutputStream();ObjectOutputStream oos = new ObjectOutputStream(out);InputStream in = socket.getInputStream();ObjectInputStream ois = new ObjectInputStream(in);// 創(chuàng)建一個(gè)遠(yuǎn)程調(diào)用對(duì)象Call call = new Call("ch12.HelloService", "echo", new Class[] { String.class }, new Object[] { "Java" });oos.writeObject(call); // 向服務(wù)器發(fā)送Call對(duì)象call = (Call) ois.readObject(); // 接收包含了方法執(zhí)行結(jié)果的Call對(duì)象System.out.println(call.getResult());ois.close();oos.close();socket.close();}public static void main(String args[]) throws Exception {new SimpleClient().invoke();} }

如上述代碼所示,客戶端 SimpleClient 類的主要作用是建立與服務(wù)器的連接,然后將帶有調(diào)用信息的 Call 對(duì)象發(fā)送到服務(wù)器端。

服務(wù)器端 SimpleServer 類在收到調(diào)用請(qǐng)求之后會(huì)使用反射機(jī)制動(dòng)態(tài)調(diào)用指定對(duì)象的指定方法,再將執(zhí)行結(jié)果返回給客戶端。

SimpleServer 類的實(shí)現(xiàn)代碼如下:

import java.io.*; import java.net.*; import java.util.*; import java.lang.reflect.*;public class SimpleServer {private Map remoteObjects = new HashMap(); // 存放遠(yuǎn)程對(duì)象的緩存/** 把一個(gè)遠(yuǎn)程對(duì)象放到緩存中 */public void register(String className, Object remoteObject) {remoteObjects.put(className, remoteObject);}public void service() throws Exception {ServerSocket serverSocket = new ServerSocket(8000);System.out.println("服務(wù)器啟動(dòng).");while (true) {Socket socket = serverSocket.accept();InputStream in = socket.getInputStream();ObjectInputStream ois = new ObjectInputStream(in);OutputStream out = socket.getOutputStream();ObjectOutputStream oos = new ObjectOutputStream(out);Call call = (Call) ois.readObject(); // 接收客戶發(fā)送的Call對(duì)象System.out.println(call);call = invoke(call); // 調(diào)用相關(guān)對(duì)象的方法oos.writeObject(call); // 向客戶發(fā)送包含了執(zhí)行結(jié)果的Call對(duì)象ois.close();oos.close();socket.close();}}public Call invoke(Call call) {Object result = null;try {String className = call.getClassName();String methodName = call.getMethodName();Object[] params = call.getParams();Class classType = Class.forName(className);Class[] paramTypes = call.getParamTypes();Method method = classType.getMethod(methodName, paramTypes);Object remoteObject = remoteObjects.get(className); // 從緩存中取出相關(guān)的遠(yuǎn)程對(duì)象if (remoteObject == null) {throw new Exception(className + "的遠(yuǎn)程對(duì)象不存在");} else {result = method.invoke(remoteObject, params);}} catch (Exception e) {result = e;}call.setResult(result); // 設(shè)置方法執(zhí)行結(jié)果return call;}public static void main(String args[]) throws Exception {SimpleServer server = new SimpleServer();// 把事先創(chuàng)建的HelloServiceImpl對(duì)象加入到服務(wù)器的緩存中server.register("ch13.HelloService", new HelloServiceImpl());server.service();} }

由于這是一個(gè)網(wǎng)絡(luò)程序,首先需要運(yùn)行服務(wù)器端 SimpleServer,然后再運(yùn)行客戶端 SimpleClient。運(yùn)行結(jié)果是在客戶端看到輸出“echoJava”,這個(gè)結(jié)果是服務(wù)器端執(zhí)行 HelloServicelmpl 對(duì)象的 echo() 方法的返回值。下圖顯示了 SimpleClient 與 SimpleServer 的通信過程。

總結(jié)

以上是生活随笔為你收集整理的Java在远程方法调用中运用反射机制的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。