Java在远程方法调用中运用反射机制 ゞ 浴缸里的玫瑰 2021-12-17 16:45 291阅读 0赞 上一节详细介绍了如何使用 java.lang.reflect 包提供的 Constructor 类获取构造方法的信息、使用 Method 类获取成员方法的信息以及使用 Field 类获取成员变量的信息。 本案例将介绍反射机制在网络编程中的应用,实现如何在客户端通过远程方法调用服务器端的方法。 假定在服务器端有一个 HelloService 接口,该接口具有 getTime() 和 echo() 方法,具体代码如下: 1. package ch12; 2. import java.util.Date; 3. public interface HelloService 4. \{ 5. public String echo(String msg); 6. public Date getTime(); 7. \} 在服务器上创建一个 HelloServiceImpl 类并实现 HelloService 接口。HelloServiceImpl 类的代码如下: 1. package ch12; 2. import java.util.Date; 3. public class HelloServiceImpl implements HelloService 4. \{ 5. @Override 6. public String echo(String msg) 7. \{ 8. return "echo:"+msg; 9. \} 10. @Override 11. public Date getTime() 12. \{ 13. return new Date(); 14. \} 15. \} 上述代码所示,在 HelloServiceImpl 类中对 echo() 方法和 getTime() 方法进行了重写。那么,客户端如何调用服务器端 Hello-ServiceImpl 类中的 getTime() 和 echo() 方法呢? 具体方法是:客户端需要把调用的方法名、方法参数类型、方法参数值,以及方法所属的类名或接口名发送给服务器端。服务器端再调用相关对象的方法,然后把方法的返回值发送给客户端。 为了便于按照面向对象的方式来处理客户端与服务器端的通信,可以把它们发送的信息用 Call 类来表示。一个 Call 对象表示客户端发起的一个远程调用,它包括调用的类名或接口名、方法名、方法参数类型、方法参数值和方法执行结果。 Call 类的实现代码如下: 1. package ch12; 2. import java.io.Serializable; 3. public class Call implements Serializable 4. \{ 5. private String className; //表示类名或接口名 6. private String methodName; //表示方法名 7. private Class\[\] paramTypes; //表示方法参数类型 8. private Object\[\] params; //表示方法参数值 9. 10. // 表示方法的执行结果 11. // 如果方法正常执行,则result为方法返回值,如果方法抛出异常,那么result为该异常。 12. private Object result; 13. public Call()\{\} 14. public Call(String className,String methodName,Class\[\] paramTypes,Object\[\] params) 15. \{ 16. this.className=className; 17. this.methodName=methodName; 18. this.paramTypes=paramTypes; 19. this.params=params; 20. \} 21. public String getClassName() 22. \{ 23. return className; 24. \} 25. public void setClassName(String className) 26. \{ 27. this.className=className; 28. \} 29. public String getMethodName() 30. \{ 31. return methodName; 32. \} 33. 34. public void setMethodName(String methodName) 35. \{ 36. this.methodName=methodName; 37. \} 38. public Class\[\] getParamTypes() 39. \{ 40. return paramTypes; 41. \} 42. public void setParamTypes(Class\[\] paramTypes) 43. \{ 44. this.paramTypes=paramTypes; 45. \} 46. public Object\[\] getParams() 47. \{ 48. return params; 49. \} 50. public void setParams(Object\[\] params) 51. \{ 52. this.params=params; 53. \} 54. public Object getResult() 55. \{ 56. return result; 57. \} 58. public void setResult(Object result) 59. \{ 60. this.result=result; 61. \} 62. public String toString() 63. \{ 64. return "className="+className+"methodName="+methodName; 65. \} 66. \} 假设客户端为 SimpleClient,服务器端为 SimpleServer。SimpleClient 调用 SimpleServer 的 HelloServiceImpl 对象中 echo() 方法的流程如下: 1. SimpleClient 创建一个 Call 对象,它包含调用 HelloService 接口的 echo() 方法的信息。 2. SimpleClient 通过对象输出流把 Call 对象发送给 SimpleServer。 3. SimpleServer 通过对象输入流读取 Call 对象,运用反射机制调用 HelloServiceImpl 对象的 echo() 方法,把 echo() 方法的执行结果保存到 Call 对象中。 4. SimpleServer 通过对象输出流把包含方法执行结果的 Call 对象发送给 SimpleClient。 5. SimpleClient 通过对象输入流读取 Call 对象,从中获得方法执行结果。 首先来看看客户端程序 SimpleClient 类的实现代码。 1. package ch12; 2. import java.io.\*; 3. import java.net.\*; 4. import java.util.\*; 5. import java.lang.reflect.\*; 6. import java.io.\*; 7. import java.net.\*; 8. import java.util.\*; 9. public class SimpleClient 10. \{ 11. public void invoke() throws Exception 12. \{ 13. Socket [socket][]=new Socket("localhost", 8000); 14. OutputStream out=socket.getOutputStream(); 15. ObjectOutputStream oos=new ObjectOutputStream(out); 16. InputStream in=socket.getInputStream(); 17. ObjectInputStream ois=new ObjectInputStream(in); 18. //创建一个远程调用对象 19. Call call=new Call("ch12.HelloService","echo",new Class\[\]\{String.class\},new Object\[\]\{"[Java][]"\}); 20. oos.writeObject(call); //向服务器发送Call对象 21. call=(Call) ois.readObject(); //接收包含了方法执行结果的Call对象 22. System.out.println(call.getResult()); 23. ois.close(); 24. oos.close(); 25. socket.close(); 26. \} 27. public static void main(String args\[\]) throws Exception 28. \{ 29. new SimpleClient().invoke(); 30. \} 31. \} 如上述代码所示,客户端 SimpleClient 类的主要作用是建立与服务器的连接,然后将带有调用信息的 Call 对象发送到服务器端。 服务器端 SimpleServer 类在收到调用请求之后会使用反射机制动态调用指定对象的指定方法,再将执行结果返回给客户端。 SimpleServer 类的实现代码如下: 1. package ch12; 2. import java.io.\*; 3. import java.net.\*; 4. import java.util.\*; 5. import java.lang.reflect.\*; 6. public class SimpleServer 7. \{ 8. private Map remoteObjects=new HashMap(); //存放远程对象的缓存 9. /\*\* 把一个远程对象放到缓存中 \*/ 10. public void register(String className,Object remoteObject) 11. \{ 12. remoteObjects.put(className,remoteObject); 13. \} 14. public void service() throws Exception 15. \{ 16. ServerSocket serverSocket=new ServerSocket(8000); 17. System.out.println("服务器启动."); 18. while(true) 19. \{ 20. Socket socket=serverSocket.accept(); 21. InputStream in=socket.getInputStream(); 22. ObjectInputStream ois=new ObjectInputStream(in); 23. OutputStream out=socket.getOutputStream(); 24. ObjectOutputStream oos=new ObjectOutputStream(out); 25. Call call=(Call) ois.readObject(); //接收客户发送的Call对象 26. System.out.println(call); 27. call=invoke(call); //调用相关对象的方法 28. oos.writeObject(call); //向客户发送包含了执行结果的Call对象 29. ois.close(); 30. oos.close(); 31. socket.close(); 32. \} 33. \} 34. public Call invoke(Call call) 35. \{ 36. Object result=null; 37. try 38. \{ 39. String className=call.getClassName(); 40. String methodName=call.getMethodName(); 41. Object\[\] params=call.getParams(); 42. Class classType=Class.forName(className); 43. Class\[\] paramTypes=call.getParamTypes(); 44. Method method=classType.getMethod(methodName, paramTypes); 45. Object remoteObject=remoteObjects.get(className); //从缓存中取出相关的远程对象 46. if(remoteObject==null) 47. \{ 48. throw new Exception(className+"的远程对象不存在"); 49. \} 50. else 51. \{ 52. result=method.invoke(remoteObject,params); 53. \} 54. \} 55. catch(Exception e) 56. \{ 57. result=e; 58. \} 59. call.setResult(result); //设置方法执行结果 60. return call; 61. \} 62. public static void main(String args\[\]) throws Exception 63. \{ 64. SimpleServer server=new SimpleServer(); 65. // 把事先创建的HelloServiceImpl对象加入到服务器的缓存中 66. server.register("ch13.HelloService", new HelloServiceImpl()); 67. server.service(); 68. \} 69. \} 由于这是一个网络程序,首先需要运行服务器端 SimpleServer,然后再运行客户端 SimpleClient。运行结果是在客户端看到输出“echoJava”,这个结果是服务器端执行 HelloServicelmpl 对象的 echo() 方法的返回值。图 1 所示显示了 SimpleClient 与 SimpleServer 的通信过程。 ![3-1Q029104I45E.jpg][] 图1 SimpleClient与SimpleServer的通信过程 [socket]: http://c.biancheng.net/socket/ [Java]: http://c.biancheng.net/java/ [3-1Q029104I45E.jpg]: /images/20211213/963d7fac46a24f4db92ce5bad9fb20cc.png
相关 Java反射机制在代码调试中的运用示例 Java的反射机制允许我们在运行时检查类、接口、方法和字段等信息。在代码调试中,反射可以用来实现以下几种情况: 1. **获取对象信息**:如果不知道对象具体是谁,可以通过反 痛定思痛。/ 2024年09月21日 00:00/ 0 赞/ 4 阅读
相关 Java反射机制及其在代码动态调整中的运用 Java反射机制是Java语言内建的一种机制,它允许我们在运行时检查类、接口以及它们的属性和方法。 在代码动态调整中,反射机制主要应用于以下几种情况: 1. 配置文件:通过 傷城~/ 2024年09月16日 06:03/ 0 赞/ 11 阅读
相关 Java反射机制:如何动态调用方法 在Java中,反射(Reflection)是一种强大的机制,它允许我们在运行时检查类、接口和字段,以及动态调用它们的方法。 以下是如何使用Java反射动态调用方法的步骤: 约定不等于承诺〃/ 2024年09月14日 17:21/ 0 赞/ 23 阅读
相关 Java反射机制:如何动态调用方法 Java的反射机制是Java语言提供的一种允许程序在运行时检查类、字段和方法的能力。 以下是动态调用方法的基本步骤: 1. 获取对象:首先需要一个指向你想要操作的类的对象。 阳光穿透心脏的1/2处/ 2024年09月12日 16:33/ 0 赞/ 36 阅读
相关 Java反射机制运用不当:字段获取、方法调用等问题示例 Java反射机制是一种强大的工具,允许我们在运行时检查对象的结构信息,如获取和设置字段值,调用方法等。然而,如果使用不当,可能会引发安全问题或程序错误。以下是一些常见的例子: ゝ一世哀愁。/ 2024年09月10日 19:24/ 0 赞/ 22 阅读
相关 java反射机制调用方法 这是个测试用的例子,通过反射调用对象的方法。 TestRef.java import java.lang.reflect.Method; import j 女爷i/ 2022年06月09日 13:46/ 0 赞/ 243 阅读
相关 JAVA反射机制运用教程 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称 绝地灬酷狼/ 2022年06月05日 06:14/ 0 赞/ 169 阅读
相关 Java在远程方法调用中运用反射机制 上一节详细介绍了如何使用 java.lang.reflect 包提供的 Constructor 类获取构造方法的信息、使用 Method 类获取成员方法的信息以及使用 Fiel ゞ 浴缸里的玫瑰/ 2021年12月17日 16:45/ 0 赞/ 292 阅读
相关 反射机制——通过反射调用service中方法 需求:现在有一群service接口,有同一个方法名称,内部逻辑除了调用不同的调用自身的方法外其他基本都一致,那现在就需要一个独立的方法来勾勒出这个方法 1.SpringCon ﹏ヽ暗。殇╰゛Y/ 2021年09月26日 18:02/ 0 赞/ 755 阅读
还没有评论,来说两句吧...