我如何实现一个Java RMI远程方法调用的案例?

2026-05-22 18:321阅读0评论SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计2342个文字,预计阅读时间需要10分钟。

自己简单写了一个Java RMI(远程方法调用)的实现案例。为了更好地理解RMI(远程方法调用)和序列化的意义等,花费了三天多的时间。高能预警!高能预警!高能预警!

自己简单写了个Java RMI(远程方法调用)的实现案例。

为了更好理解RMI(远程方法调用)、序列化的意义等等,花费三天多的时间肝了一个Java RMI的实现案例。

!!!高能预警!!!

代码量有点大,先附上了简图用于理解

整个过程分为两大步

  • 第一步--注册过程:客户端通过指定路由获取注册中心指定的远程客户端对象
  • 第二部--服务调用过程:客户端通过远程客户端对象访问远程服务端(代理服务)从而访问到真实服务的实现

调整为舒适的姿势,慢慢看…… 废话少说,上代码!!!

1.定义远程标记接口

面向接口编程,具体作用看后面的代码怎么使用

//标记接口:直接或间接实现MyRMI接口将获得远程调用的能力 publicinterfaceMyRMI{ } 2.编写RMI 服务注册中心

注册中心类:用于注册服务和获取服务,核心是hashMap路由表对象

/** *注册中心:维护服务发布的注册表 */ publicclassMyRMIRegistry{ //默认端口 publicfinalintREGISTRY_PORT=10099; privateStringhost; privateintport; privateMap<String,MyRMI>bindings; publicMyRMIRegistry(intport){ this.port=port; } publicMyRMIRegistry(Stringhost,intport){ this.host=host; this.port=port; } publicvoidcreateRegistry(StringserverName,MyRMImyRMI){ //注册服务,并开启服务 this.bindings=newHashMap<>(); Stringhost=null; try{ host=Inet4Address.getLocalHost().getHostAddress(); }catch(UnknownHostExceptione){ e.printStackTrace(); } //路由规则可自行定义,只要能确保Key唯一即可 Stringbinding="myrmi://"+host+":"+port+"/"+serverName; this.bindings.put("myrmi://"+host+":"+port+"/"+serverName,myRMI); System.out.println("注册的服务有:"+bindings.keySet().toString()); MyRMIRegistryServermyRMIRegistryServer=newMyRMIRegistryServer(this.port,this.bindings); Executors.newCachedThreadPool().submit(myRMIRegistryServer);//线程池启动服务 } publicMyRMIgetRegistry(StringserverName){ Socketsocket=null; ObjectOutputStreamout=null; ObjectInputStreamin=null; MyRMImyRMI=null; //通过 try{ socket=newSocket(host,port); out=newObjectOutputStream(socket.getOutputStream()); out.writeObject("myrmi://"+host+":"+port+"/"+serverName); in=newObjectInputStream(socket.getInputStream()); myRMI=(MyRMI)in.readObject(); }catch(IOExceptione){ e.printStackTrace(); }catch(ClassNotFoundExceptione){ e.printStackTrace(); } returnmyRMI; } }

RMI 注册中心获取服务的线程:启动注册中心服务,等待客户端来获取路由表中的远程客户端

/** *RMI注册中心获取服务线程 */ publicclassMyRMIRegistryServerimplementsRunnable{ privateintport; privateMap<String,MyRMI>bindings; publicMyRMIRegistryServer(Integerport,Map<String,MyRMI>bindings){ this.port=port; this.bindings=bindings; } @Override publicvoidrun(){ ServerSocketserverSocket=null; ObjectOutputStreamout=null; ObjectInputStreamin=null; try{ serverSocket=newServerSocket(this.port); while(true){ Socketsocket=serverSocket.accept(); in=newObjectInputStream(socket.getInputStream()); out=newObjectOutputStream(socket.getOutputStream()); //看看客户端想要什么服务 StringserverName=(String)in.readObject(); Iteratoriterator=bindings.keySet().iterator(); while(iterator.hasNext()){ Stringkey=(String)iterator.next(); if(serverName.equals(key)){ //给客户端响应服务对象 MyRMImyRMI=bindings.get(key); out.writeObject(myRMI); } } } }catch(IOExceptione){ e.printStackTrace(); }catch(ClassNotFoundExceptione){ e.printStackTrace(); }finally{ //异常后进入 try{ if(out!=null)out.close(); if(in!=null)in.close(); if(serverSocket!=null)serverSocket.close(); }catch(IOExceptione){ e.printStackTrace(); } } } } 3.定义要发布的服务接口

需要提供RMI服务的接口,必须继承自定义的MyRMI标记接口

/** *服务接口 */ publicinterfaceHelloextendsMyRMI{ publicStringsayHello(Stringname); } 4.服务用到的实体类

/** *对象数据类:Person */ publicclassPersonimplementsSerializable{ //序列化版本UID privatestaticfinallongserialVersionUID=1L; privateStringname; privateintage; privateStringsex; publicStringgetName(){ returnname; } publicvoidsetName(Stringname){ this.name=name; } publicintgetAge(){ returnage; } publicvoidsetAge(intage){ this.age=age; } publicStringgetSex(){ returnsex; } publicvoidsetSex(Stringsex){ this.sex=sex; } @Override publicStringtoString(){ return"Person{"+"name='"+name+",age="+age+",sex='"+sex+'}'; } publicPerson(){ } publicPerson(Stringname,Integerage,Stringsex){ this.name=name; this.age=age; this.sex=sex; } } 5.实现要发布的服务接口

/** *对外提供的服务实现 */ publicclassHelloImplimplementsHello{ privatestaticFilefile=newFile("D:/HelloRMI.txt"); privatestaticList<Person>list=newArrayList<>(); @Override publicStringsayHello(Stringname){ Stringresult="没有获取到"+name+"的信息"; try{ List<Person>personList=readList(); for(Personperson:personList){ if(person.getName().equals(name)){ result="Hello,welcometotheRMI!" +"姓名:"+name+"年龄:"+person.getAge()+"性别:"+person.getSex(); } } }catch(IOExceptione){ e.printStackTrace(); }catch(ClassNotFoundExceptione){ e.printStackTrace(); } returnresult; } /** *生成数据,为测试做准备 *@paramargs *@throwsIOException *@throwsClassNotFoundException */ publicstaticvoidmain(String[]args)throwsIOException,ClassNotFoundException{ //数据准备:集合类都实现了序列化接口Serializable list.add(newPerson("张三",38,"男")); list.add(newPerson("李四",38,"男")); list.add(newPerson("如花",18,"女")); //持久化对象数据 writerList(list); //查询持久化对象数据 List<Person>personList=readList(); System.out.println("遍历持久化对象数据>"); for(Personperson:personList){ System.out.println(person); if(person.getAge()==38){ person.setAge(18); } } } publicstaticvoidwriterList(List<Person>list)throwsIOException{ ObjectOutputStreamobjectOutputStream=newObjectOutputStream(newFileOutputStream(file)); objectOutputStream.writeObject(list); objectOutputStream.close(); } publicstaticList<Person>readList()throwsIOException,ClassNotFoundException{ //读取普通文件反序列化 ObjectInputStreamobjectInputStream=newObjectInputStream(newFileInputStream(file)); List<Person>personList=(List<Person>)objectInputStream.readObject(); objectInputStream.close(); returnpersonList; } } 6.远程客户端的线程类

用于自动生成服务接口(继承了MyRMI标记接口)的远程客户端类:这个类原本是通用类实现,为了方便实现,就直接实现Hello接口了

/** *远程客户端的线程类的生成: *为了方便实现,这边直接实现服务接口编写 */ publicclassHelloClientThreadimplementsHello,Serializable{ //序列化版本UID privatestaticfinallongserialVersionUID=1L; privateMap<String,Object>map=newHashMap<>();//报文对象:方法名和参数对象 privateStringip; privateintport; publicHelloClientThread(Stringip,intport){ this.ip=ip; this.port=port; } @Override publicStringsayHello(Stringname){ map.put("sayHello",name); Stringresult=(String)send(); returnresult; } privateObjectsend(){ Objecto=null; Socketsocket=null; ObjectOutputStreamout=null; ObjectInputStreamin=null; try{ socket=newSocket(ip,port); out=newObjectOutputStream(socket.getOutputStream()); in=newObjectInputStream(socket.getInputStream()); //告诉服务端我要调用什么服务 out.writeObject(map); //获取服务实现对象 o=in.readObject(); }catch(IOExceptione){ e.printStackTrace(); }catch(ClassNotFoundExceptione){ e.printStackTrace(); }finally{ try{ if(out!=null)out.close(); if(in!=null)in.close(); if(socket!=null)socket.close(); }catch(IOExceptione){ e.printStackTrace(); } } returno; } } 7.远程服务端的线程类

用于自动生成服务接口(继承了MyRMI标记接口)的远程服务端类:这个类原本也是通用类实现,为了方便实现,部分代码尚未做到解耦通用

/** *远程服务端的线程类的生成: *为了方便实现,这边直接实现服务线程类 */ publicclassHelloServerThreadimplementsRunnable{ privateIntegerport; privateMyRMImyRMI; publicHelloServerThread(Integerport,MyRMImyRMI){ this.port=port; this.myRMI=myRMI; } @Override publicvoidrun(){ ServerSocketserverSocket=null; ObjectOutputStreamout=null; ObjectInputStreamin=null; try{ serverSocket=newServerSocket(this.port); while(true){ Socketsocket=serverSocket.accept(); in=newObjectInputStream(socket.getInputStream()); out=newObjectOutputStream(socket.getOutputStream()); //看看客户端想要什么服务 Mapmap=(Map)in.readObject(); Iteratoriterator=map.keySet().iterator(); while(iterator.hasNext()){ Stringkey=(String)iterator.next(); if("sayHello".equals(key)){ //给客户端响应服务对象 Hellohello=(Hello)myRMI; Stringresult=hello.sayHello((String)map.get(key)); out.writeObject(result); } } } }catch(IOExceptione){ e.printStackTrace(); }catch(ClassNotFoundExceptione){ e.printStackTrace(); }finally{ //异常后进入 try{ if(out!=null)out.close(); if(in!=null)in.close(); if(serverSocket!=null)serverSocket.close(); }catch(IOExceptione){ e.printStackTrace(); } } } } 8.远程客户端生成和远程服务端生成和启动的类

/** *远程客户端生成和远程服务端生成和启动的类 */ publicclassRemoteSocketObject{ //默认端口 privateintport=18999; //指定远程通讯端口和代理服务 publicMyRMIcreateRemoteClient(MyRMImyRMI,intport){ if(port>0) this.port=port; MyRMImyRMIClient=null; try{ //生成底层通讯服务端,并启动 HelloServerThreadhelloServerThread=newHelloServerThread(this.port,myRMI); Executors.newCachedThreadPool().submit(helloServerThread);//线程池启动服务 //生成底层通讯客户端 StringlocalHost=Inet4Address.getLocalHost().getHostAddress(); System.out.println("host="+localHost+",port="+this.port); myRMIClient=newHelloClientThread(localHost,this.port); }catch(Exceptione){ e.printStackTrace(); } returnmyRMIClient; } } 9.服务发布类

/** *RMI服务发布类 */ publicclassHelloServer{ publicstaticvoidmain(String[]args){ System.out.println("CreateHelloRemoteMethodInvocation..."); //实例化一个Hello Hellohello=newHelloImpl(); //转换成远程服务,并提供远程客户端 HelloremoteClient=(Hello)newRemoteSocketObject().createRemoteClient(hello,0); //将服务实现托管到Socket服务 MyRMIRegistrymyRMIRegistry=newMyRMIRegistry(16000); //开启线程服务 myRMIRegistry.createRegistry("Hello",remoteClient); } } 10.客户端测试类

/** *客户端测试类 *客户端只知道服务接口、服务发布的地址和服务发布的名称 */ publicclassTestHello{ publicstaticvoidmain(String[]args){ //注意不是127.0.0.1,不知道host的看server端启动后打印的信息 //端口16000是注册中心的端口,底层代理服务的端口客户端无需知道 MyRMIRegistryclient=newMyRMIRegistry("192.168.233.1",16000); Hellohello=(Hello)client.getRegistry("Hello"); System.out.println(hello.sayHello("张三")); } } 11.总结

所有代码整下来,在真正的场景中:

客户端只知道:TestHello类、Hello接口定义、MyRMI标记接口、MyRMIRegistry注册类代码(路由表中只知道Key,不知道具体值);

服务端只知道:Hello接口、HelloImpl服务实现类、MyRMI标记接口、MyRMIRegistry注册类代码(路由表中知道Key和具体值);

关于其他的代码实现都是无感的,为了简单实现远程客户端和远程服务端,将服务接口耦合到两者上了,未做到解耦通用。

Java往期文章

Java全栈学习路线、学习资源和面试题一条龙

我心里优秀架构师是怎样的?

免费下载经典编程书籍

更多优质文章和资源

标签:实现

本文共计2342个文字,预计阅读时间需要10分钟。

自己简单写了一个Java RMI(远程方法调用)的实现案例。为了更好地理解RMI(远程方法调用)和序列化的意义等,花费了三天多的时间。高能预警!高能预警!高能预警!

自己简单写了个Java RMI(远程方法调用)的实现案例。

为了更好理解RMI(远程方法调用)、序列化的意义等等,花费三天多的时间肝了一个Java RMI的实现案例。

!!!高能预警!!!

代码量有点大,先附上了简图用于理解

整个过程分为两大步

  • 第一步--注册过程:客户端通过指定路由获取注册中心指定的远程客户端对象
  • 第二部--服务调用过程:客户端通过远程客户端对象访问远程服务端(代理服务)从而访问到真实服务的实现

调整为舒适的姿势,慢慢看…… 废话少说,上代码!!!

1.定义远程标记接口

面向接口编程,具体作用看后面的代码怎么使用

//标记接口:直接或间接实现MyRMI接口将获得远程调用的能力 publicinterfaceMyRMI{ } 2.编写RMI 服务注册中心

注册中心类:用于注册服务和获取服务,核心是hashMap路由表对象

/** *注册中心:维护服务发布的注册表 */ publicclassMyRMIRegistry{ //默认端口 publicfinalintREGISTRY_PORT=10099; privateStringhost; privateintport; privateMap<String,MyRMI>bindings; publicMyRMIRegistry(intport){ this.port=port; } publicMyRMIRegistry(Stringhost,intport){ this.host=host; this.port=port; } publicvoidcreateRegistry(StringserverName,MyRMImyRMI){ //注册服务,并开启服务 this.bindings=newHashMap<>(); Stringhost=null; try{ host=Inet4Address.getLocalHost().getHostAddress(); }catch(UnknownHostExceptione){ e.printStackTrace(); } //路由规则可自行定义,只要能确保Key唯一即可 Stringbinding="myrmi://"+host+":"+port+"/"+serverName; this.bindings.put("myrmi://"+host+":"+port+"/"+serverName,myRMI); System.out.println("注册的服务有:"+bindings.keySet().toString()); MyRMIRegistryServermyRMIRegistryServer=newMyRMIRegistryServer(this.port,this.bindings); Executors.newCachedThreadPool().submit(myRMIRegistryServer);//线程池启动服务 } publicMyRMIgetRegistry(StringserverName){ Socketsocket=null; ObjectOutputStreamout=null; ObjectInputStreamin=null; MyRMImyRMI=null; //通过 try{ socket=newSocket(host,port); out=newObjectOutputStream(socket.getOutputStream()); out.writeObject("myrmi://"+host+":"+port+"/"+serverName); in=newObjectInputStream(socket.getInputStream()); myRMI=(MyRMI)in.readObject(); }catch(IOExceptione){ e.printStackTrace(); }catch(ClassNotFoundExceptione){ e.printStackTrace(); } returnmyRMI; } }

RMI 注册中心获取服务的线程:启动注册中心服务,等待客户端来获取路由表中的远程客户端

/** *RMI注册中心获取服务线程 */ publicclassMyRMIRegistryServerimplementsRunnable{ privateintport; privateMap<String,MyRMI>bindings; publicMyRMIRegistryServer(Integerport,Map<String,MyRMI>bindings){ this.port=port; this.bindings=bindings; } @Override publicvoidrun(){ ServerSocketserverSocket=null; ObjectOutputStreamout=null; ObjectInputStreamin=null; try{ serverSocket=newServerSocket(this.port); while(true){ Socketsocket=serverSocket.accept(); in=newObjectInputStream(socket.getInputStream()); out=newObjectOutputStream(socket.getOutputStream()); //看看客户端想要什么服务 StringserverName=(String)in.readObject(); Iteratoriterator=bindings.keySet().iterator(); while(iterator.hasNext()){ Stringkey=(String)iterator.next(); if(serverName.equals(key)){ //给客户端响应服务对象 MyRMImyRMI=bindings.get(key); out.writeObject(myRMI); } } } }catch(IOExceptione){ e.printStackTrace(); }catch(ClassNotFoundExceptione){ e.printStackTrace(); }finally{ //异常后进入 try{ if(out!=null)out.close(); if(in!=null)in.close(); if(serverSocket!=null)serverSocket.close(); }catch(IOExceptione){ e.printStackTrace(); } } } } 3.定义要发布的服务接口

需要提供RMI服务的接口,必须继承自定义的MyRMI标记接口

/** *服务接口 */ publicinterfaceHelloextendsMyRMI{ publicStringsayHello(Stringname); } 4.服务用到的实体类

/** *对象数据类:Person */ publicclassPersonimplementsSerializable{ //序列化版本UID privatestaticfinallongserialVersionUID=1L; privateStringname; privateintage; privateStringsex; publicStringgetName(){ returnname; } publicvoidsetName(Stringname){ this.name=name; } publicintgetAge(){ returnage; } publicvoidsetAge(intage){ this.age=age; } publicStringgetSex(){ returnsex; } publicvoidsetSex(Stringsex){ this.sex=sex; } @Override publicStringtoString(){ return"Person{"+"name='"+name+",age="+age+",sex='"+sex+'}'; } publicPerson(){ } publicPerson(Stringname,Integerage,Stringsex){ this.name=name; this.age=age; this.sex=sex; } } 5.实现要发布的服务接口

/** *对外提供的服务实现 */ publicclassHelloImplimplementsHello{ privatestaticFilefile=newFile("D:/HelloRMI.txt"); privatestaticList<Person>list=newArrayList<>(); @Override publicStringsayHello(Stringname){ Stringresult="没有获取到"+name+"的信息"; try{ List<Person>personList=readList(); for(Personperson:personList){ if(person.getName().equals(name)){ result="Hello,welcometotheRMI!" +"姓名:"+name+"年龄:"+person.getAge()+"性别:"+person.getSex(); } } }catch(IOExceptione){ e.printStackTrace(); }catch(ClassNotFoundExceptione){ e.printStackTrace(); } returnresult; } /** *生成数据,为测试做准备 *@paramargs *@throwsIOException *@throwsClassNotFoundException */ publicstaticvoidmain(String[]args)throwsIOException,ClassNotFoundException{ //数据准备:集合类都实现了序列化接口Serializable list.add(newPerson("张三",38,"男")); list.add(newPerson("李四",38,"男")); list.add(newPerson("如花",18,"女")); //持久化对象数据 writerList(list); //查询持久化对象数据 List<Person>personList=readList(); System.out.println("遍历持久化对象数据>"); for(Personperson:personList){ System.out.println(person); if(person.getAge()==38){ person.setAge(18); } } } publicstaticvoidwriterList(List<Person>list)throwsIOException{ ObjectOutputStreamobjectOutputStream=newObjectOutputStream(newFileOutputStream(file)); objectOutputStream.writeObject(list); objectOutputStream.close(); } publicstaticList<Person>readList()throwsIOException,ClassNotFoundException{ //读取普通文件反序列化 ObjectInputStreamobjectInputStream=newObjectInputStream(newFileInputStream(file)); List<Person>personList=(List<Person>)objectInputStream.readObject(); objectInputStream.close(); returnpersonList; } } 6.远程客户端的线程类

用于自动生成服务接口(继承了MyRMI标记接口)的远程客户端类:这个类原本是通用类实现,为了方便实现,就直接实现Hello接口了

/** *远程客户端的线程类的生成: *为了方便实现,这边直接实现服务接口编写 */ publicclassHelloClientThreadimplementsHello,Serializable{ //序列化版本UID privatestaticfinallongserialVersionUID=1L; privateMap<String,Object>map=newHashMap<>();//报文对象:方法名和参数对象 privateStringip; privateintport; publicHelloClientThread(Stringip,intport){ this.ip=ip; this.port=port; } @Override publicStringsayHello(Stringname){ map.put("sayHello",name); Stringresult=(String)send(); returnresult; } privateObjectsend(){ Objecto=null; Socketsocket=null; ObjectOutputStreamout=null; ObjectInputStreamin=null; try{ socket=newSocket(ip,port); out=newObjectOutputStream(socket.getOutputStream()); in=newObjectInputStream(socket.getInputStream()); //告诉服务端我要调用什么服务 out.writeObject(map); //获取服务实现对象 o=in.readObject(); }catch(IOExceptione){ e.printStackTrace(); }catch(ClassNotFoundExceptione){ e.printStackTrace(); }finally{ try{ if(out!=null)out.close(); if(in!=null)in.close(); if(socket!=null)socket.close(); }catch(IOExceptione){ e.printStackTrace(); } } returno; } } 7.远程服务端的线程类

用于自动生成服务接口(继承了MyRMI标记接口)的远程服务端类:这个类原本也是通用类实现,为了方便实现,部分代码尚未做到解耦通用

/** *远程服务端的线程类的生成: *为了方便实现,这边直接实现服务线程类 */ publicclassHelloServerThreadimplementsRunnable{ privateIntegerport; privateMyRMImyRMI; publicHelloServerThread(Integerport,MyRMImyRMI){ this.port=port; this.myRMI=myRMI; } @Override publicvoidrun(){ ServerSocketserverSocket=null; ObjectOutputStreamout=null; ObjectInputStreamin=null; try{ serverSocket=newServerSocket(this.port); while(true){ Socketsocket=serverSocket.accept(); in=newObjectInputStream(socket.getInputStream()); out=newObjectOutputStream(socket.getOutputStream()); //看看客户端想要什么服务 Mapmap=(Map)in.readObject(); Iteratoriterator=map.keySet().iterator(); while(iterator.hasNext()){ Stringkey=(String)iterator.next(); if("sayHello".equals(key)){ //给客户端响应服务对象 Hellohello=(Hello)myRMI; Stringresult=hello.sayHello((String)map.get(key)); out.writeObject(result); } } } }catch(IOExceptione){ e.printStackTrace(); }catch(ClassNotFoundExceptione){ e.printStackTrace(); }finally{ //异常后进入 try{ if(out!=null)out.close(); if(in!=null)in.close(); if(serverSocket!=null)serverSocket.close(); }catch(IOExceptione){ e.printStackTrace(); } } } } 8.远程客户端生成和远程服务端生成和启动的类

/** *远程客户端生成和远程服务端生成和启动的类 */ publicclassRemoteSocketObject{ //默认端口 privateintport=18999; //指定远程通讯端口和代理服务 publicMyRMIcreateRemoteClient(MyRMImyRMI,intport){ if(port>0) this.port=port; MyRMImyRMIClient=null; try{ //生成底层通讯服务端,并启动 HelloServerThreadhelloServerThread=newHelloServerThread(this.port,myRMI); Executors.newCachedThreadPool().submit(helloServerThread);//线程池启动服务 //生成底层通讯客户端 StringlocalHost=Inet4Address.getLocalHost().getHostAddress(); System.out.println("host="+localHost+",port="+this.port); myRMIClient=newHelloClientThread(localHost,this.port); }catch(Exceptione){ e.printStackTrace(); } returnmyRMIClient; } } 9.服务发布类

/** *RMI服务发布类 */ publicclassHelloServer{ publicstaticvoidmain(String[]args){ System.out.println("CreateHelloRemoteMethodInvocation..."); //实例化一个Hello Hellohello=newHelloImpl(); //转换成远程服务,并提供远程客户端 HelloremoteClient=(Hello)newRemoteSocketObject().createRemoteClient(hello,0); //将服务实现托管到Socket服务 MyRMIRegistrymyRMIRegistry=newMyRMIRegistry(16000); //开启线程服务 myRMIRegistry.createRegistry("Hello",remoteClient); } } 10.客户端测试类

/** *客户端测试类 *客户端只知道服务接口、服务发布的地址和服务发布的名称 */ publicclassTestHello{ publicstaticvoidmain(String[]args){ //注意不是127.0.0.1,不知道host的看server端启动后打印的信息 //端口16000是注册中心的端口,底层代理服务的端口客户端无需知道 MyRMIRegistryclient=newMyRMIRegistry("192.168.233.1",16000); Hellohello=(Hello)client.getRegistry("Hello"); System.out.println(hello.sayHello("张三")); } } 11.总结

所有代码整下来,在真正的场景中:

客户端只知道:TestHello类、Hello接口定义、MyRMI标记接口、MyRMIRegistry注册类代码(路由表中只知道Key,不知道具体值);

服务端只知道:Hello接口、HelloImpl服务实现类、MyRMI标记接口、MyRMIRegistry注册类代码(路由表中知道Key和具体值);

关于其他的代码实现都是无感的,为了简单实现远程客户端和远程服务端,将服务接口耦合到两者上了,未做到解耦通用。

Java往期文章

Java全栈学习路线、学习资源和面试题一条龙

我心里优秀架构师是怎样的?

免费下载经典编程书籍

更多优质文章和资源

标签:实现