内容简介:本博客猫叔的博客,转载请申明出处首先RMI(Remote Method Invocation)是Java特有的一种RPC实现,它能够使部署在不同主机上的Java对象进行通信与方法调用,它是一种基于Java的远程方法调用技术。让我们优先来实现一个RMI的RPC案例吧。
本博客猫叔的博客,转载请申明出处
学习系列
Java自带RPC实现,RMI框架入门
首先RMI(Remote Method Invocation)是 Java 特有的一种RPC实现,它能够使部署在不同主机上的Java对象进行通信与方法调用,它是一种基于Java的远程方法调用技术。
让我们优先来实现一个RMI的RPC案例吧。
项目源码地址: RPC_Demo ,记得是项目里面的 comgithubrmi
- 1、首先我们需要为服务端创建一个接口方法,而且这个接口最好继承
Remote
package com.github.rmi.server; import java.rmi.Remote; import java.rmi.RemoteException; /** * Create by UncleCatMySelf in 21:03 2019\4\20 0020 */ public interface MyService extends Remote { String say(String someOne)throws RemoteException; }
- 2、对于接口实现类,RMI接口方法定义必须显式声明抛出RemoteException异常,服务端方法实现必须继承UnicastRemoteObject类,该类定义了服务调用与服务提供方对象实现,并建立一对一的连接。
package com.github.rmi.server; import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; /** * Create by UncleCatMySelf in 21:05 2019\4\20 0020 */ public class MyServiceImpl extends UnicastRemoteObject implements MyService { protected MyServiceImpl() throws RemoteException { } public String say(String someOne) throws RemoteException { return someOne + ",Welcome to Study!"; } }
- 3、这里我们还需要一个针对服务端的配置类,因为RMI的通信端口是随机产生的,因此有可能会被防火墙拦截。为了防止被防火墙拦截,需要强制制定RMI的通信端口,一般通过自定义一个RMISocketFactory类来实现。
package com.github.rmi.config; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.rmi.server.RMISocketFactory; /** * Create by UncleCatMySelf in 21:15 2019\4\20 0020 */ public class CustomerSocketFactory extends RMISocketFactory { public Socket createSocket(String host, int port) throws IOException { return new Socket(host, port); } public ServerSocket createServerSocket(int port) throws IOException { if (port == 0){ port = 8855; } System.out.println("RMI 通信端口 : " + port); return new ServerSocket(port); } }
- 4、好了,这时你可以写出服务端的启动代码了。
package com.github.rmi.server; import com.github.rmi.config.CustomerSocketFactory; import java.rmi.Naming; import java.rmi.registry.LocateRegistry; import java.rmi.server.RMISocketFactory; /** * Create by UncleCatMySelf in 21:07 2019\4\20 0020 */ public class ServerMain { public static void main(String[] args) throws Exception { //注册服务 LocateRegistry.createRegistry(8866); //指定通信端口,防止被防火墙拦截 RMISocketFactory.setSocketFactory(new CustomerSocketFactory()); //创建服务 MyService myService = new MyServiceImpl(); Naming.bind("rmi://localhost:8866/myService",myService); System.out.println("RMI 服务端启动正常"); } }
- 5、客户端的启动就相对比较简单,我们仅需要进入服务,并调用对应的远程方法即可。
package com.github.rmi.client; import com.github.rmi.server.MyService; import java.rmi.Naming; /** * Create by UncleCatMySelf in 21:10 2019\4\20 0020 */ public class ClientMain { public static void main(String[] args) throws Exception { //服务引入 MyService myService = (MyService) Naming.lookup("rmi://localhost:8866/myService"); //调用远程方法 System.out.println("RMI 服务端调用返回:" + myService.say("MySelf")); } }
最后可以看看效果。
关于RMI的一些关键点
- 支持真正的面向对象的多态性,这是RMI的优势。
- 完美支持Java语言所独有的特性,不支持其他语言。
- 使用了Java原生序列化,所有序列化对象必须实现java.io.Serializablie接口。
- 底层通信是BIO(同步阻塞I/O)实现的Socket
- 由于BIO与原生序列化存在的性能问题,导致RMI的性能较差,如果你的项目性能要求较高,可能并不合适哦!
公众号:Java猫说
学习交流群:728698035
现架构设计(码农)兼创业技术顾问,不羁平庸,热爱开源,杂谈程序人生与不定期干货。
以上所述就是小编给大家介绍的《RPC框架是啥之Java自带RPC实现,RMI框架入门》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- .NET 程序如何获取图片的宽高(框架自带多种方法的不同性能)
- laravel自带用户认证
- Mac自带apache配置
- opencv自带例子学习-图像混合
- Golang中自带的强大命令工具
- Android调用系统自带的分享功能
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
ACM程序设计培训教程
吴昊 / 中国铁道 / 2007-8 / 28.0
《ACM程序设计培训教程》不是这些专门问题的教科书,所以对这些问题所涉及知识的介绍不多,主要是分析一个个案例,介绍专属于ACM程序设计的方法和技巧。一起来看看 《ACM程序设计培训教程》 这本书的介绍吧!