我们将介绍反射机制在网络编程中的应用,实现如何在客户端通过远程方法调用服务器端的方法。

假定在服务器端有一个 HelloService 接口,该接口具有 getTime() 和 echo() 方法,具体代码如下:

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

在服务器上创建一个 HelloServiceImpl 类并实现 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 类中对 echo() 方法和 getTime() 方法进行了重写。那么,客户端如何调用服务器端 Hello-ServiceImpl 类中的 getTime() 和 echo() 方法呢?

具体方法是:客户端需要把调用的方法名、方法参数类型、方法参数值,以及方法所属的类名或接口名发送给服务器端。服务器端再调用相关对象的方法,然后把方法的返回值发送给客户端。

为了便于按照面向对象的方式来处理客户端与服务器端的通信,可以把它们发送的信息用 Call 类来表示。一个 Call 对象表示客户端发起的一个远程调用,它包括调用的类名或接口名、方法名、方法参数类型、方法参数值和方法执行结果。

Call 类的实现代码如下:

import java.io.Serializable;public class Call implements Serializable {private static final long serialVersionUID = 6659953547331194808L;private String className; // 表示类名或接口名private String methodName; // 表示方法名private Class[] paramTypes; // 表示方法参数类型private Object[] params; // 表示方法参数值// 表示方法的执行结果// 如果方法正常执行,则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;}
}

假设客户端为 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 类的实现代码。

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);// 创建一个远程调用对象Call call = new Call("ch12.HelloService", "echo", new Class[] { String.class }, new Object[] { "Java" });oos.writeObject(call); // 向服务器发送Call对象call = (Call) ois.readObject(); // 接收包含了方法执行结果的Call对象System.out.println(call.getResult());ois.close();oos.close();socket.close();}public static void main(String args[]) throws Exception {new SimpleClient().invoke();}
}

如上述代码所示,客户端 SimpleClient 类的主要作用是建立与服务器的连接,然后将带有调用信息的 Call 对象发送到服务器端。

服务器端 SimpleServer 类在收到调用请求之后会使用反射机制动态调用指定对象的指定方法,再将执行结果返回给客户端。

SimpleServer 类的实现代码如下:

import java.io.*;
import java.net.*;
import java.util.*;
import java.lang.reflect.*;public class SimpleServer {private Map remoteObjects = new HashMap(); // 存放远程对象的缓存/** 把一个远程对象放到缓存中 */public void register(String className, Object remoteObject) {remoteObjects.put(className, remoteObject);}public void service() throws Exception {ServerSocket serverSocket = new ServerSocket(8000);System.out.println("服务器启动.");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(); // 接收客户发送的Call对象System.out.println(call);call = invoke(call); // 调用相关对象的方法oos.writeObject(call); // 向客户发送包含了执行结果的Call对象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); // 从缓存中取出相关的远程对象if (remoteObject == null) {throw new Exception(className + "的远程对象不存在");} else {result = method.invoke(remoteObject, params);}} catch (Exception e) {result = e;}call.setResult(result); // 设置方法执行结果return call;}public static void main(String args[]) throws Exception {SimpleServer server = new SimpleServer();// 把事先创建的HelloServiceImpl对象加入到服务器的缓存中server.register("ch13.HelloService", new HelloServiceImpl());server.service();}
}

由于这是一个网络程序,首先需要运行服务器端 SimpleServer,然后再运行客户端 SimpleClient。运行结果是在客户端看到输出“echoJava”,这个结果是服务器端执行 HelloServicelmpl 对象的 echo() 方法的返回值。下图显示了 SimpleClient 与 SimpleServer 的通信过程。

Java在远程方法调用中运用反射机制相关推荐

  1. 浅说Java中的反射机制(一)

    在学习传智播客李勇老师的JDBC系列时,会出现反射的概念,由于又是第一次见,不免感到陌生.所以再次在博客园找到一篇文章,先记录如下: 引用自java中的反射机制,作者bingoideas.(()为我手 ...

  2. java代码安全检测机制_全面解析:java中的反射机制,内含代码验证解析

    什么是反射? 在运行状态中,对于任意一个类,都能够获取到这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性(包括私有的方法和属性),这种动态获取的信息以及动态调用对象的方法的功 ...

  3. formdata 接受参数中带有class 对象_浅析JAVA中的反射机制及对Servlet的优化

    今天来聊聊java中的反射机制,工作以后发现很多东西动不动就要使用反射或者动态代理,如果不能很好的理解反射,那么对于动态代理等一些重要的设计模式就会有种不够通透的感觉. 所谓的反射,就是在运行状态中, ...

  4. java反射机制是什么_java中的反射机制是什么?

    java中的反射机制是什么? 发布时间:2020-05-21 22:45:50 来源:亿速云 阅读:156 作者:鸽子 java:"一切即对象",感觉java语言本身在不断践行着这 ...

  5. java中的反射机制是什么

    给大家介绍一下java中的反射机制,java中反射机制更体现出了java的灵活性.多态.和类之间的耦合性. 1:反射是一种间接操作目标对象的机制,只要给定类的名字,就可以通过反设机制获取所有的类信息. ...

  6. Java中的反射机制详讲

    Java中的反射机制详讲 1.反射机制_介绍_Class对象获取 2.反射机制_动态操作_构造器_方法_属性 3.动态编译_DanamicCompile_反射调用main方法问题 好文推荐:排序.查找 ...

  7. 【反射机制】Java中的反射机制,使用反射机制创建对象、访问属性、方法、构造方法等

    这篇文章主要是整理了Java中的反射机制,包括:反射机制概念.反射机制访问构造方法.反射机制访问普通方法.反射机制访问属性,反射机制访问修饰符. 目录 一.反射机制概念 二.反射机制使用 (1)加载C ...

  8. 深入理解Java类型信息(Class对象)与反射机制

    关联文章: 深入理解Java类型信息(Class对象)与反射机制 深入理解Java枚举类型(enum) 深入理解Java注解类型(@Annotation) 深入理解Java并发之synchronize ...

  9. 初探GO中的反射机制

    Go中的反射机制 反射是什么东西? 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力. 在Go 语言中,提供了一种机制在运行时更新变量和检查它 ...

最新文章

  1. C语言---二分法搜索
  2. elasticsearch数据长期保存的方案
  3. centos7 安装 mysql5.7
  4. 【学习笔记】20、日期和时间模快
  5. 计算机丢失quartz.dll什么意思,win7系统中出现缺少quartz.dll文件的修复方法
  6. sql重复数据取日期小的_excel快速查询重复数据的3个小技巧
  7. R与Python或协同助力机器学习:听Azure ML Studio讲座有感
  8. 矩阵运算_Eigen使用_旋转矩阵/角轴/欧拉角/四元数相互转换
  9. Eureka 自我保护模式、健康检查机制、Eureka 元数据
  10. 莫再用唐僧式的唠叨施加影响----家长式管理者实施HOLA的障碍
  11. 离职,我应该做什么?
  12. Cloud Foundry 运行bosh create-env时报错: TLS handshake timeout
  13. html 占用空间 滚动轴_html – 缩放子级上的溢出滚动:X和Y轴上的不同行为
  14. 女人要关注男人的几大点
  15. 任务栏信息栏中图标闪动
  16. 微信之父张小龙的2359篇日记
  17. Scratch软件编程等级考试四级——20210626
  18. cs6导入库闪退 flash_flash cs6导入某些mp3不能的解决办法
  19. 瑞禧-近红外荧光核酸银纳米团簇/3~10nm非荧光银纳米颗粒以及PEI-AgNCs等纳米金属团簇的分类
  20. php.ini 优化 oa,OA办公系统常见问题解答

热门文章

  1. python requests get post_python+requests进行get、post方法接口测试
  2. windows7系统软件无法卸载的解决方法
  3. 如何理解面向过程和面向对象?
  4. jeecg框架alert消息样式
  5. get请求,参数值为json字符串如何传值
  6. MySQL:错误代码1215 无法添加外键约束的解决思路
  7. php 域名白名单,域名白名单验证
  8. android--多线程,android多线程
  9. mysql 转型_MySQL的未来在哪?
  10. 计算机组成原理上机实验报告.doc,计算机组成原理第二次上机实验报告.doc