在上一篇学习dubbo时 提到RMI,远程调用,下面找了篇不错的文章 学习下:http://6221123.blog.51cto.com/6211123/1112619
Java远程方法调用,即Java RMI(Java Remote Method Invocation)是Java编程语言里,一种用于实现远程过程调用的应用程序编程接口。它使客户机上运行的程序可以调用远程服务器上的对象。远程方法调用特性使Java编程人员能够在网络环境中分布操作。RMI全部的宗旨就是尽可能简化远程接口对象的使用。
Java RMI极大地依赖于接口。在需要创建一个远程对象的时候,程序员通过传递一个接口来隐藏底层的实现细节。客户端得到的远程对象句柄正好与本地的根代码连接,由后者负责透过网络通信。这样一来,程序员只需关心如何通过自己的接口句柄发送消息。
接口的两种常见实现方式是:最初使用JRMP(Java Remote Message Protocol,Java远程消息交换协议)实现;此外还可以用与CORBA兼容的方法实现。RMI一般指的是编程接口,也有时候同时包括JRMP和API(应用程序编程接口),而RMI-IIOP则一般指RMI接口接管绝大部分的功能,以支持CORBA的实现。
最初的RMI API设计为通用地支持不同形式的接口实现。后来,CORBA增加了传值(pass by value)功能,以实现RMI接口。然而RMI-IIOP和JRMP实现的接口并不完全一致。
这里讲述的是基于JDK1.5的RMI程序搭建,更简单的说是一个 HelloWorld RMI。
1. 这里是基于JDK1.5的,节省了繁琐的手工编译(生成桩和骨架)。不像1.4之前的RMI。
2. 这里是把客户端和服务器端的两个程序,分布在两个独立的程序里面,而不是同一个package下面。是真正的分布式。
3. 这里不过多阐述原理,这只是一个Hello World!!
好,以下是步骤:
1. 在Eclipse里面创建一个server 端的project。然后,创建一个接口,这个接口是你要向client端开放的方法定义。它叫做:UserManagerInterface,而且必须继承Remote接口。
1. package dataserver.rmi.stub;
2.
3. import java.rmi.Remote;
4. import java.rmi.RemoteException;
5.
6. import dataserver.rmi.bean.Account;
7.
8. public interface UserManagerInterface extends Remote{
9. public String getUserName() throws RemoteException;
10. public Account getAdminAccount() throws RemoteException;
11. }
2. 为了证明RMI中,“面向对象”或者是“无缝传递JAVA Object”是何等简单,我们需要定义一个Account类,该类是一个Bean,必须实现implements Serializable序列化接口。这是一个可以在client和server传输的可序列化对象。
1. package dataserver.rmi.bean;
2.
3. import java.io.Serializable;
4.
5. public class Account implements Serializable,Cloneable{
6.
7. /**
8. *
9. */
10. private static final long serialVersionUID = -1858518369668584532L;
11. private String username;
12. private String password;
13.
14. public String getUsername() {
15. return username;
16. }
17. public void setUsername(String username) {
18. this.username = username;
19. }
20. public String getPassword() {
21. return password;
22. }
23. public void setPassword(String password) {
24. this.password = password;
25. }
26.
27. }
3. 此时,需要实现你已经开放的接口:
1. package dataserver.rmi;
2.
3. import java.rmi.RemoteException;
4.
5. import dataserver.rmi.bean.Account;
6. import dataserver.rmi.stub.UserManagerInterface;
7.
8. public class UserManagerImpl implements UserManagerInterface {
9.
10. public UserManagerImpl() throws RemoteException {
11. //super();
12. // TODO Auto-generated constructor stub
13. //UnicastRemoteObject.exportObject(this);
14. }
15.
16. /**
17. *
18. */
19. private static final long serialVersionUID = -3111492742628447261L;
20.
21. public String getUserName() throws RemoteException {
22. // TODO Auto-generated method stub
23. return "Tommy Lee";
24. }
25.
26. public Account getAdminAccount() throws RemoteException {
27. // TODO Auto-generated method stub
28. new Account();
29. "admin");
30. "admin");
31. return account;
32. }
33.
34. }
4. 定义一个主程序入口,注册你已经实现的RMI接口,包括开放端口等。其实很简单:
把我们的接口名称,命名为“userManager”,方便client进行调用
1. package dataserver.entry;
2.
3. import java.rmi.AlreadyBoundException;
4. import java.rmi.RemoteException;
5. import java.rmi.registry.LocateRegistry;
6. import java.rmi.registry.Registry;
7. import java.rmi.server.UnicastRemoteObject;
8.
9. import dataserver.rmi.UserManagerImpl;
10. import dataserver.rmi.stub.UserManagerInterface;
11.
12. public class Entry {
13.
14. public static void main(String []args) throws AlreadyBoundException, RemoteException{
15.
16.
17. new UserManagerImpl();
18. 0);
19. // Bind the remote object's stub in the registry
20. 2001);
21. "userManager", userManagerI);
22. "server is ready");
23. }
24. }
5. Server端的代码已经全部写完,但是还要把bean类(Account)和接口类(UserMangerInterface)打包成jar,以便可以在下面导入进client端的项目中。
项目--》右键--》导出--》jar--》选择bean和interface--》命名为RmiServerInterface.jar--》finish
6. 开始创建client端的程序。新建一个project。创建完成后,把刚才jar包导入进client的项目中。
7. 导入我们的接口jar以后,可以开始编写一个client端的主程序,并调用server端的方法。
1. package weiblog.rmi;
2. import java.rmi.NotBoundException;
3. import java.rmi.RemoteException;
4. import java.rmi.registry.LocateRegistry;
5. import java.rmi.registry.Registry;
6.
7. import dataserver.rmi.stub.UserManagerInterface;
8.
9. public class Entry2 {
10.
11. public static void main(String []args){
12.
13. try {
14. "localhost",2001);
15. "userManager");
16. ""+userManager.getAdminAccount().getUsername()
17. +userManager.getAdminAccount().getPassword());
18. catch (RemoteException e) {
19. // TODO Auto-generated catch block
20. e.printStackTrace();
21. catch (NotBoundException e) {
22. // TODO Auto-generated catch block
23. e.printStackTrace();
24. }
25.
26. }
27. }
8. 启动server端的主程序,然后启动client端的主程序。
server控制台打印:server is ready
client控制台打印:adminadmin
大功告成!!