多虚拟机JVM的程序运行
– 启动多个main程序,这些程序可以部署在多个计算机上。
– 多个进程可以通过网络互相传递信息进行协作。
– 进程通过RMI可调用另外一个机器上面的java程序。
RMI的参数和返回值。
1. (自动化)传递远程对象(实现Remote接口)
只传递参数,操作位于服务端,最后服务端返回处理结果。
客户端:
- 创建上下文对象。
- 选择要访问的地址信息。
- 依据定义好的存根类,调用服务端的相关类的相关方法。
- 获取结果并输出。
//存根类
package warehouse1;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface Watehouse extends Remote{
double getPrice(String descrition)throws RemoteException;;
}
package warehouse1;
import javax.naming.*;
import java.util.*;
import java.rmi.*;
public class WarehouseClient {
public static void main(String[] args) throws NamingException, RemoteException {
Context namingContext = new InitialContext();
//开始查找注册表中有哪些绑定的服务,并打印下来。
System.out.print("RMI 注册表绑定列表:");
Enumeration<NameClassPair> e = ((InitialContext) namingContext).list("rmi://127.0.0.1:8001/");
while(e.hasMoreElements())
System.out.println(e.nextElement().getName());
//获取某一地址上的服务
String url = "rmi://127.0.0.1:8001/warehouse1";
Watehouse centralWarehouse = (Watehouse) namingContext.lookup(url);
//输入参数,获取结果
String name = "面包机";
double price = centralWarehouse.getPrice(name);
System.out.println(name + "的价格为:" + price);
}
}
服务端:
- 定义存根接口。
- 实现存根接口中的方法,完成相应的功能。
- 创建服务端对象,并将其绑定在相应的RMI注册中心。
//存根类
package warehouse1;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface Watehouse extends Remote{
double getPrice(String descrition) throws RemoteException;;
}
//实现类
package warehouse1;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.HashMap;
import java.util.Map;
public class WarehouseReal extends UnicastRemoteObject implements Watehouse{
private Map<String, Double> prices;
public WarehouseReal() throws RemoteException {
prices = new HashMap<>();
prices.put("面包机", 23.12);
prices.put("豆浆机", 12.12);
}
@Override
public double getPrice(String descrition) {
double price = prices.get(descrition);
if (price == 0)
return 0;
else
return price;
}
}
//服务端设置
package warehouse1;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
/**
* 产生WarehouseImpl对象,并进行注册在8001端口,对外提供服务
*/
public class WareouseServer {
public static void main(String[] args) throws RemoteException, MalformedURLException {
System.out.println("产生服务器对象!");
WarehouseReal centralWarehouse = new WarehouseReal();
System.out.println("服务器对象绑定8001端口,对外提供服务!");
//定义端口号
int port = 8001;
LocateRegistry.createRegistry(port);
//j将服务器对象绑定在8001端口
Naming.rebind("rmi://127.0.0.1:8001/warehouse1", centralWarehouse);
System.out.println("服务器对象启动!");
}
}
这里是在本机上操作的。
注意,在两个工程下,要是都创建了包,保持包的名称一致,不然可能出现,路径超不到的异常。
2. (自动化)传递可序列化对象(实现Serializable接口)
服务端的程序,依据客户端需要,得到相关对象;
对象经过序列化之后,通过网络,传递到客户端;
对象在客户端重新还原为一个Java对象。