Java RMI 指的是远程方法调用 (Remote Method Invocation)。
它是一种机制,能够让在某个 Java 虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法。
以下是rmi远程方法调用实现代码:
服务端
1、定义远程服务调用接口Product
import java.rmi.Remote;
import java.rmi.RemoteException;
/**
* 产品服务接口
* @author Administrator
*
*/
public interface Product extends Remote{
/**
* 获取产品描述
* @return
* @throws RemoteException
*/
public String getDescription()throws RemoteException;
}
2、Product的实现ProductImpl
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class ProductImpl extends UnicastRemoteObject implements Product{
private String descr;
public ProductImpl(String descr) throws RemoteException{
this.descr = descr;
}
@Override
public String getDescription() throws RemoteException {
return "i am a " + descr + ", buy me";
}
}
3、发布服务接口
import java.rmi.Naming;
import java.rmi.registry.LocateRegistry;
import com.zooper.rmi.ProductImpl;
public class ProductServer {
public static void main(String[] args) throws Exception {
ProductImpl p1 = new ProductImpl("blackwell toaster");
ProductImpl p2 = new ProductImpl("zapXpress Microware Oven");
/*
* 本地主机上的远程对象注册表Registry的实例,并指定端口为8888,
* 这一步必不可少(Java默认端口是1099),必不可缺的一步,
* 缺少注册表创建,则无法绑定对象到远程注册表上
*/
LocateRegistry.createRegistry(8888);
//发布服务
Naming.bind("rmi://localhost:8888/toaster",p1);
Naming.bind("rmi://localhost:8888/Microware",p2);
System.out.println("rmi服务发布成功!");
}
}
这时服务端的代码已经完成,此时执行ProductServer的main()方法即可将发布成功。
客户端
这里要注意的是:客户端程序可能需要操作服务器端的对象,但它实际上并不需要这些对象的拷贝,这些对象仍然位于服务器端,客户端代码只需要知道这些对象可以用来做什么,而他们的功能通过接口被表示了出来,这些接口是客户端与服务器共享的,并且必须同时存在于客户端与服务器端,因此客户端也需要创建Product接口.
1、定义远程服务接口Product
/**
* 定义远程调用接口
* @author Administrator
*
*/
public interface Product extends Remote{
public String getDescription()throws RemoteException;
}
2、客户端调用远程接口ProductClient
import java.rmi.Naming;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NameClassPair;
import javax.naming.NamingEnumeration;
import com.zooper.rmi.Product;
/**
* 调用远程rmi接口
* @author Administrator
*
*/
public class ProductClient {
public static void main(String[] args) throws Exception{
/*
* 获取注册成功的服务列表
* 方式一
*/
String[] servers = Naming.list("rmi://localhost:8888/");
for (String name : servers) {
System.out.println(name);
}
/*
* 获取注册成功的服务列表
* 方式二
*/
Context namingContext = new InitialContext();
NamingEnumeration<NameClassPair> e = namingContext.list("rmi://localhost:8888/");
while(e.hasMore()){
System.out.println(e.next().getName());
}
/*
* 请求接口
*/
Product p1 = (Product) Naming.lookup("rmi://localhost:8888/toaster");
System.out.println(p1.getDescription());
Product p2 = (Product) Naming.lookup("rmi://localhost:8888/Microware");
System.out.println(p2.getDescription());
}
}
这样客户端就算写好了,如果服务器端服务已经运行,此时执行ProductClient的main()方法就可以调用服务器端的远程rmi接口了。结果如下:
//localhost:8888/Microware
//localhost:8888/toaster
Microware
toaster
i am a blackwell toaster, buy me
i am a zapXpress Microware Oven, buy me
客户端和服务端的实现代码地址:
https://github.com/zZooper/RMI.git