在java的开发中不可避免的遇到java网络编程,RMI,EJB的使用,他们的关系是什么呢? RMI,远程方法调用(Remote Method Invocation)是Enterprise JavaBeans的支柱,是建立分布式Java应用程序的方便途径。RMI是非常容易使用的,但是它非常的强大。RMI的基于特定接口,RMI构架基于一个重要的原理:定义接口和定义接口的具体实现是分开的。
RMI基本原理
要实现网络机器间的通讯,首先得来看看计算机系统网络通信的基本原理,在底层层面去看,网络通信需要做的就是将流从一台计算机传输到另外一台计算机,基于传输协议和网络IO来实现,其中传输协议比较出名的有http、tcp、udp等等,http、tcp、udp都是在基于Socket概念上为某类应用场景而扩展出的传输协议,网络IO,主要有bio、nio、aio三种方式,所有的分布式应用通讯都基于这个原理而实现,只是为了应用的易用,各种语言通常都会提供一些更为贴近应用易用的应用层协议。
由此可知RMI底层采用网络编程的,既RMi基于套接字编程的,RMI是EJB远程调用的基础,仅用RMI技术就可以实现远程调用,使用EJB是为了实现组件,事物,资源池,集群等功能。
下面RMI学习:
服务接口:
package com.easyway.space.basic.network.sockets.rmi; import java.rmi.Remote; import java.rmi.RemoteException; /** * Rmi服务接口 * 创建远程接口及声明远程方法 * 远程服务接口实现java.rmi.Remote 的接口 * * @author longgangbai * */ public interface RmiMonitorService extends Remote{ public int interactive(int funindex ,String param)throws RemoteException; }
服务接口的实现:
package com.easyway.space.basic.network.sockets.rmi; import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; /** * Rmi服务接口的实现 * 实现远程接口及远程方法(继承UnicastRemoteObject) * RMI 实现UnicastRemoteObject类必须实现相关的空构造函数并抛出RemoteException * @author longgangbai * */ public class RmiMonitorServiceImpl extends UnicastRemoteObject implements RmiMonitorService{ /** * */ private static final long serialVersionUID = 1L; /** * 空构造函数 * @throws RemoteException */ protected RmiMonitorServiceImpl() throws RemoteException { super(); } /** * 服务请求频率和监控信息 * @param funindex * @param param */ public int interactive(int funindex, String param) throws RemoteException { return funindex; } }
启动并注册RMI服务:
package com.easyway.space.basic.network.sockets.rmi; import java.net.MalformedURLException; import java.rmi.AlreadyBoundException; import java.rmi.Naming; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; /** * Rmi远程监控的服务端 * * 启动RMI注册服务,并注册远程对象 * * @author longgangbai * */ public class RmiMonitorServer { public String host="localhost"; public int port=8889; /** * 初始化远程服务的方法 */ public void init(){ try { //注册本地端口 LocateRegistry.createRegistry(port); RmiMonitorService monitor=new RmiMonitorServiceImpl(); //rmi绑定本地目录和命名服务 Naming.bind("//"+host+":"+port+"/monitor",monitor); } catch (MalformedURLException e) { System.out.println("发生URL异常!" +e.getMessage());; } catch (AlreadyBoundException e) { System.out.println("发生重复绑定对象异常!" +e.getMessage()); }catch (RemoteException e) { System.out.println("创建远程对象发生异常!" +e.getMessage()); } } public static void main(String[] args) { RmiMonitorServer rmi=new RmiMonitorServer(); System.out.println("RMI服务初始化....."); rmi.init(); } }
客户端查找并使用存根:
package com.easyway.space.basic.network.sockets.rmi; import java.net.MalformedURLException; import java.rmi.Naming; import java.rmi.NotBoundException; import java.rmi.RemoteException; import java.util.HashMap; import java.util.Map; /** * Rmi监控的客户端的服务 * * 客户端查找远程对象,并调用远程方法 * * @author longgangbai * */ public class RmiMonitorClient { //用户缓存使用的实例 public Map<Class,Object> serviceMap=new HashMap<Class,Object>(); public RmiMonitorService monitorService; public String ip="localhost"; public int port=8889; public int interactive(int funindex ,String param) { try { if(monitorService==null) { monitorService=getMonitorService(RmiMonitorService.class); } return monitorService.interactive(funindex, param); } catch (RemoteException e) { e.printStackTrace(); } return 0; } /** * 查找服务对象的应用 * @param clazz * @return */ public RmiMonitorService getMonitorService(Class clazz){ try { Object object=serviceMap.get(clazz); if(object==null) { monitorService=(RmiMonitorService)Naming.lookup("rmi://"+ip+":"+port+"/monitor"); serviceMap.put(RmiMonitorService.class, monitorService); }else{ monitorService=(RmiMonitorService)serviceMap.get(clazz); } return monitorService; } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NotBoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } return monitorService; } public static void main(String[] args) { RmiMonitorClient client=new RmiMonitorClient(); int result=client.interactive(9, "i love you"); System.out.println("result ="+result); } }