Spring与Rmi的集成与应用

一篇关于在Spring框架下使用RMI的好文章。

http://blog.csdn.net/leon709/article/details/7090436

  最近应用到了Java RMI技术,所以总结一下RMI的使用,另外EJB的实现也是以Java RMI为基础核心的。RMI远程方法调用,可以跨机器通过网络调用,不过Java RMI只支持两边都是Java程序,如果要实现完全两边异构,那么就要用到传说中的Web Service了。为了看好效果,都要建立两个或两个以上工程,当然,如果你有两个机器并通过局域网相连更好,如果能同有互联网的条件就更好了,以下是同一机器不同工程的实验

Java RMI

首先新建一个工程,随便什么工程,为了方便,就Java Project吧。

1、创建一个接口,继承Remote

[java]  view plain copy
  1. package leon.rmi.iface;  
  2.   
  3. import java.rmi.Remote;  
  4. import java.rmi.RemoteException;  
  5.   
  6. /** 
  7. * 定义远程接口,必须继承Remote接口, 
  8. * 其中所有需要远程调用的方法都必须抛出RemoteException异常  
  9. */   
  10. public interface IHello extends Remote {   
  11.     public String sayHello(String name) throws RemoteException;   
  12.     public int sum(int a, int b)throws RemoteException;  
  13. }  

2、创建接口的实现类

[java]  view plain copy
  1. package leon.rmi.impl;  
  2.   
  3. import java.rmi.RemoteException;  
  4. import java.rmi.server.UnicastRemoteObject;  
  5.   
  6. import leon.rmi.iface.IHello;  
  7.   
  8. public class HelloImpl extends UnicastRemoteObject implements IHello {  
  9.   
  10.     private static final long serialVersionUID = 1L;  
  11.   
  12.     public HelloImpl() throws RemoteException {  
  13.         super();  
  14.     }  
  15.   
  16.     @Override  
  17.     public String sayHello(String name) throws RemoteException {  
  18.         return "Welcome, " + name;  
  19.     }  
  20.   
  21.     @Override  
  22.     public int sum(int a, int b) throws RemoteException{  
  23.         return a + b;  
  24.     }  
  25. }  

说明:接口的实现类同时要实现Serializable接口,这里继承UnicastRemoteObject也是间接实现Serializable接口,同时,因为构造方法需要抛出RemoteException,所以不能缺省使用隐含的无参构造方法,而应该自己显式定义构造方法。

 

3、创建应用类,注册和启动服务端RMI,以被客户端调用

[java]  view plain copy
  1. package leon.rmi.impl;  
  2.   
  3. import java.net.MalformedURLException;  
  4. import java.rmi.AlreadyBoundException;  
  5. import java.rmi.Naming;  
  6. import java.rmi.RemoteException;  
  7. import java.rmi.registry.LocateRegistry;  
  8.   
  9. import leon.rmi.iface.IHello;  
  10.   
  11. public class HelloServer {  
  12.     public static void main(String args[]) {  
  13.         try {  
  14.             //创建一个远程对象  
  15.             IHello rhello = new HelloImpl();      
  16.             //生成远程对象注册表Registry的实例,并指定端口为8888(默认端口是1099)  
  17.             LocateRegistry.createRegistry(8888);  
  18.   
  19.             //把远程对象注册到RMI注册服务器上,并命名为RHello  
  20.             //绑定的URL标准格式为:rmi://host:port/name(协议名可以省略,下面两种写法都可以)  
  21.             Naming.bind("rmi://10.225.112.86:8888/RHello", rhello);  
  22.             //Naming.bind("//10.225.112.86:8888/RHello",rhello);  
  23.   
  24.             System.out.println(">>INFO:远程IHello对象绑定成功!");  
  25.         } catch (RemoteException e) {  
  26.             System.out.println("创建远程对象发生异常!");  
  27.             e.printStackTrace();  
  28.         } catch (AlreadyBoundException e) {  
  29.             System.out.println("发生重复绑定对象异常!");  
  30.             e.printStackTrace();  
  31.         } catch (MalformedURLException e) {  
  32.             System.out.println("发生URL畸形异常!");  
  33.             e.printStackTrace();  
  34.         }  
  35.     }  
  36. }  

说明:绑定的地址10.225.112.86是我的局域网地址可以在DOS命令行用ipconfig查看,如果你的机器没有任何联网,可以使用127.0.0.1或localhost。

运行HelloServer.java看到,红色方块显示正在运行:

        >>INFO:远程IHello对象绑定成功!

好了,现在远程服务提供端建立完成,下面建立客户端。

新建一个新的工程,为了方便,也是Java Project吧,

1、 因为客户端需要有服务端那边提供的接口,才可以访问,所以要将服务端的IHello接口完全拷贝(连同包)到客户端,当然为了方便,你在客户端工程中新建一个完全一样的接口也可以。实际运用中通常是要服务端接口打成jar包来提供的。

2、 创建客户端调用类

[java]  view plain copy
  1. package testrmi;  
  2.   
  3. import java.rmi.Naming;  
  4.   
  5. import leon.rmi.iface.IHello;  
  6.   
  7. public class HelloClient {  
  8.     public static void main(String args[]) {  
  9.         try {  
  10.             // 在RMI服务注册表中查找名称为RHello的对象,并调用其上的方法  
  11.             IHello rhello = (IHello) Naming.lookup("rmi://10.225.112.86:8888/RHello");  
  12.             System.out.println(rhello.sayHello("水哥"));  
  13.             System.out.println(rhello.sum(4545457));  
  14.         } catch (Exception e) {  
  15.             e.printStackTrace();  
  16.         }  
  17.     }  
  18. }  

运行,显示,成功。

呵呵,是不是很简单?对吧。

下面我们要使用Spring封装的Java RMI技术,也是很多项目都会用到的。后面我有个Spring RMI的例子。要看懂下面Spring的例子,你需要已经会用Spring,会配置Spring,否则怕你看不懂,所以如果还不懂Spring的,先学学Spring,入下门吧。

Spring RMI

       Spring RMI中,主要有两个类:org.springframework.remoting.rmi.RmiServiceExporterorg.springframework.remoting.rmi.RmiProxyFactoryBean

服务端使用RmiServiceExporter暴露RMI远程方法,客户端用RmiProxyFactoryBean间接调用远程方法。

 

   首先,也是两个工程,服务端用Web工程,因为使用Spring,我们依托Web容器来完成。

1、在该服务端Web工程中添加接口,普通接口,无需继承其他

[java]  view plain copy
  1. package leon.rmi.iface;  
  2.   
  3. public interface IUserDao {  
  4.     public String getUserList();  
  5.     public int sum(int a, int b);  
  6. }  

  2、接口的实现类

[java]  view plain copy
  1. package leon.rmi.impl;  
  2.   
  3. import leon.rmi.iface.IUserDao;  
  4.   
  5. public class UserDaoImpl implements IUserDao {  
  6.   
  7.     @Override  
  8.     public String getUserList() {  
  9.         return "Hello,Get the user list from database!";  
  10.     }  
  11.   
  12.     @Override  
  13.     public int sum(int a, int b) {  
  14.         return a+b;  
  15.     }  
  16. }  

3、在该服务端Web工程中添加Spring的bean配置文件,比如命名为rmi.xml,内容如下:

[html]  view plain copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2.   
  3. <beans:beans xmlns="http://www.springframework.org/schema/security"  
  4.     xmlns:beans="http://www.springframework.org/schema/beans"  
  5.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  6.     xsi:schemaLocation="http://www.springframework.org/schema/beans  
  7.     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
  8.     http://www.springframework.org/schema/security  
  9.     http://www.springframework.org/schema/security/spring-security-3.0.xsd">  
  10.   
  11.     <beans:bean id="userDaoRmi" class="leon.rmi.impl.UserDaoImpl">   
  12.     </beans:bean>   
  13.       
  14.     <beans:bean id="userSvcExporter" class="org.springframework.remoting.rmi.RmiServiceExporter">   
  15.         <beans:property name="service" ref="userDaoRmi"/>   
  16.         <beans:property name="serviceName" value="userDaoService"/>   
  17.         <beans:property name="serviceInterface" value="leon.rmi.iface.IUserDao"/>   
  18.         <beans:property name="registryPort" value="9111"/>   
  19.         <beans:property name="servicePort" value="10023"/>   
  20.     </beans:bean>   
  21. </beans:beans>  

   说明:这里不详细的说明了,主要配置了真实实现类,用RmiServiceExporter暴露时,配置property要注意的有service,serviceName,serviceInterface,端口registryPort。

   启动Web工程的服务器,该配置文件应该被Spring的监听器监听,并加载,启动成功后,服务端就算建好了。如果服务器是在localhost启动的,那么暴露的RMI的IP也是localhost,如果需要使用其他IP,需要让服务器在其他的IP启动。

好了,吃完午饭继续写
客户端调用

为了方便也只新建一个简单的Java Project,使用静态的java代码来调用了。

1、 在源文件src下建立一个springbeans.xml

[html]  view plain copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2.   
  3. <beans:beans xmlns="http://www.springframework.org/schema/security"  
  4.     xmlns:beans="http://www.springframework.org/schema/beans"  
  5.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  6.     xsi:schemaLocation="http://www.springframework.org/schema/beans  
  7.     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
  8.     http://www.springframework.org/schema/security  
  9.     http://www.springframework.org/schema/security/spring-security-3.0.xsd">  
  10.       
  11.     <beans:bean id="userDaoProxy" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">   
  12.         <beans:property name="serviceUrl" value="rmi://localhost:9111/userDaoService"/>   
  13.         <beans:property name="serviceInterface" value="leon.rmi.iface.IUserDao"/>   
  14.     </beans:bean>  
  15.       
  16. </beans:beans>  

这里注意到RmiProxyFactoryBean的两个重要的property:serviceUrlserviceInterface,IUserDao接口可以从服务端的接口打成jar包来提供。

 

2、 新建java类

[java]  view plain copy
  1. package testrmi;  
  2.   
  3. import leon.rmi.iface.IUserDao;  
  4.   
  5. import org.springframework.context.ApplicationContext;  
  6. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  7.   
  8. public class TestRMI2 {  
  9.     public static void main(String[] args) {  
  10.          ApplicationContext ctx = new ClassPathXmlApplicationContext("springbeans.xml");  
  11.          IUserDao userDao = (IUserDao) ctx.getBean("userDaoProxy");  
  12.          System.out.println(userDao.getUserList());  
  13.          System.out.println(userDao.sum(145487));  
  14.     }  
  15. }  

运行,成功。

好了,这就是一个采用Spring封装的RMI的例子,项目工作中应该经常使用的。

有什么问题,欢迎讨论交流。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值