peace唠叨

RMI(远程方法调用)介绍

本文简单介绍下RMI。即Java RMI(Java Remote Method Invocation)是Java编程语言里,一种用于实现远程过程调用的应用程序编程接口。它使客户机上运行的程序可以调用远程服务器上的对象。远程方法调用特性使Java编程人员能够在网络环境中分布操作。RMI全部的宗旨就是尽可能简化远程接口对象的使用。

全部代码下载:Github链接:github链接,点击惊喜;写文章不易,欢迎大家采我的文章,以及给出有用的评论,当然大家也可以关注一下我的github;多谢;

1.RMI介绍

RMI(Remote Method Invocation)远程方法调用是一种计算机之间利用远程对象互相调用实现双方通讯的一种通讯机制。使用这种机制,某一台计算机上的对象可以调用另外一台计算机上的对象来获取远程数据。
RMI是针对JAVA有效的RPC,常用于一个jvm中调用另外一个jvm中的Service方法获得数据。

2.RMI原理:

RMI流程原理如下图:
00
1.rmi服务注册他的名字和IP到RMI注册中心(bind)
2.rmi客户端通过IP和名字去RMI注册中心找相应的服务(lookup)
3.rmi Stub序列化调用的方法和参数编组后传给rmi Skeleton(call)
4.rmi skeleton执行stub的逆过程,调用真实的server类执行该方法(invocation)
5.rmi skeleton将调用函数的结果返回给stub(return)

3.开发步骤:jdk8

3.1.定义远程接口

1
2
3
4
5
6
7
8
9
10
11
12
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.List;
/**
* 接口须继承Remote
* 方法需要抛出RemoteException
* @author peace
*
*/

public interface StudentService extends Remote{
public List<Student> getAllStudent()throws RemoteException;
}

3.2开发JRMI服务类并实现第一步的接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.List;
/**
* 接口实现类
* 需要继承UnicastRemoteObject
* @author peace
*
*/

public class StudnetServiceImpl extends UnicastRemoteObject implements StudentService{
protected StudnetServiceImpl() throws RemoteException {
super();
}
@Override
public List<Student> getAllStudent() throws RemoteException {
/**
* 这里使用假数据,项目开发时再这里调用dao方法。
*/

List<Student> students=new ArrayList<>();
for(int i=0;i<5;i++){
Student student=new Student();
student.setName("peace"+i);
student.setAge(22+i);
students.add(student);
}
return students;
}
}

3.3开发服务启动主方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public static void main(String[] args) {

try {
//需要远程机器访问时,需要设置hostname
System.setProperty("java.rmi.server.hostname", "192.168.1.112");
System.out.println("服务准备启动");
//加上此程序,就可以不要在控制台上开启RMI的注册程序(rmiregistry),1099是RMI服务监视的默认端口
LocateRegistry.createRegistry(1099);
StudentService service=new StudnetServiceImpl();
//通过java 名字服务技术,可以讲具体的RMI Server实现绑定一个访问路径。注册到LocateRegistry中
Naming.rebind("rmi://192.168.1.112:1099/hello",service);
System.out.println("服务启动成功");

} catch (RemoteException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
}
}

3.4开发客户调用程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.util.List;
public class RemoteClient {
public static void main(String[] args) {
try {
/**
* 客户端通过loockup找到对应的服务对象。
*
*/

StudentService service=(StudentService)Naming.lookup("rmi://192.168.1.112:1099/hello");
//可以进行方法调用
List<Student> allStudent = service.getAllStudent();
for(Student student:allStudent)
{
System.out.println("name :"+student.getName());
}
} catch (MalformedURLException | RemoteException | NotBoundException e) {
e.printStackTrace();
}
}
}

3.4启动与测试

1.启动remote服务
01
2.启动client
02

4.在不同JVM的远程调用测试:

直接将clinet的class(RemoteClient.class)以及接口的class(StudentService.class)拷贝到其他机器上就行;
得到的结果与上面一样。注意的就是要注明远程服务的名字:
如: System.setProperty(“java.rmi.server.hostname”, “192.168.1.112”);
可能有人问stub和skeleton在哪里,这是因为我使用的是jdk8中这些都是动态生成的,不需要人为再使用rmic命令生成了。
假如小伙伴们用的不是jdk8,可以参考下面链接:http://blog.csdn.net/yinwenjie/article/details/49120813

本文来自伊豚(blog.wpeace.cn)

Peace wechat
欢迎您扫一扫上面的微信公众号,订阅我的博客!
坚持原创技术分享,您的支持将鼓励我继续创作!