Java EE之RMI
开始学Java EE,为什么不从Servlet,JSP学起,而偏要选择一个在如今企业级开发中基本上不会直接用到的RMI,是因为大名鼎鼎而又臭名昭著但又不得不学的EJB建立在RMI基础之上。怀揣着李约瑟那句“如果我们不了解过去,也没多少希望掌握未来。”, 我开始盘根问底似的去学习Java EE的历史版本,于是我选择了EJB2,于是我选择了RMI。
提到分布式计算,一开始有RPC,COBRA,Windows下的COM+。J2EE横空出世后,RMI也迅速加入了分布式大家庭中。
RMI实现了这么一种应用场景:从一个JVM中的对象调用另一个JVM中的对象方法,是一种典型的C/S构架。首先将Server端的对象注册到rmiregistry中,Client找到该对象,然后调用该对象的方法。如果方法调用的参数也是对象,不管是传入的还是返回的,那么这样的对象需要序列化,即实现Serializable接口。
在Server端首先需要定义一个远程接口,该接口需要继承Remote接口,以表明可以被远程调用。远程接口定义了向Client提供服务的方法,真正提供服务的对象需要实现这些方法。为了使Client端能够捕获到有可能发生的异常,Server端对象的每一个方法都应该抛出RemoteException异常。
定义好Server端的服务接口和相应的对象后,通过rmic命令生成stub,stub运行在客户端,相当于Server端对象为Client端提供的代理,Client端在调用Server端的方法是通过stub完成的。
接下来运行rmiregistry,注意此时的路径应该为Server端对象包名的顶层目录。如果你打算通过codebase的方式从Server端自动下载stub,那么运行rmiregistry时,stub便不应该放到classpath下,而应该通过java.rmi.server.codebase选项将stub加到codebase中,比如在启动Server时:
java -Djava.rmi.server.codebase=http://localhost:2001/ -Djava.secutiry.policy=securiy.policy Server
Java提供了一个默认的codebase server,启动非常简单。
在Server端绑定对象时可以通过两种方法,一种是通过Naming.bind的方式,另一种是通过JNDI的方式。