`

Spring 使用RMI

    博客分类:
  • rmi
 
阅读更多

 

Spring提供类用于集成各种远程访问技术。这种对远程访问的支持可以降低你在用POJO实现支持远程访问业务时的开发难度。目前,Spring提供对下面四种远程访问技术的支持:
远程方法调用(RMI)。通过使用RmiProxyFactoryBean和RmiServiceExporter,Spring支持传统的RMI(使用java.rmi.Remote interfaces 和 java.rmi.RemoteException)和通过RMI调用器(可以使用任何Java接口)的透明远程调用。

Spring的HTTP调用器。Spring提供一种特殊的远程调用策略支持任何Java接口(象RMI调用器一样),它允许Java序列化能够通过HTTP传送。对应的支持类是HttpInvokerProxyFactoryBean和HttpInvokerServiceExporter。

Hessian。通过使用HessianProxyFactoryBean和HessianServiceExporter,你可以使用Caucho提供的轻量级基于HTTP的二进制协议透明地提供你的业务。

Burlap。Burlap是基于XML的,它可以完全代替Hessian。Spring提供的支持类有BurlapProxyFactoryBean和BurlapServiceExporter。

JAX RPC (TODO).

RMI是不能够穿越防火墙的,在网上也查了一些资料,但根据其提供的方法都没有成功,唉,功夫不负有心人,经过一番努力,还是把它实现了,其实这东西就是一层窗纸,捅破了也没有什么太难得,废话不说了,我们开始吧。(不好意思,还得再说一句废话:得益于罗士飞的那本spring教程代码)。

在此之前,我先把目录结构抓取个图像给大家看看。


当然首先要把spring的相关依赖的jar包引入了。这里就不能描述了。

先写服务器段代码:
1. 定义接口 ILogPerson.java
package com.openv.spring;

public interface ILogPerson {
     public String getPersion(PersonVO personVO);
}

2. 定义POJO PersonVO.java
package com.openv.spring;

import java.io.Serializable;

public class PersonVO implements Serializable {
     private String firstname;
     private String lastname;

     public String getFirstname() {
         return firstname;
     }

     public void setFirstname(String firstname) {
         this.firstname = firstname;
     }

     public String getLastname() {
         return lastname;
     }

     public void setLastname(String lastname) {
         this.lastname = lastname;
     }
}

注意:这里的PersonVO.java 必须继承Serializable 以实现序列化,不然会抱错,谨记!


3. 定义实现:LogPerson.java
package com.openv.spring;

public class LogPerson implements ILogPerson{

     public String getPersion(PersonVO personVO) {
         return personVO.getFirstname()+" @#@ "+personVO.getLastname(); 
     }
}

4. 定义spring的依赖注入的文件appcontextrmiserver.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
    "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>

<bean id="logPerson" class="com.openv.spring.LogPerson"/>

<bean id="logPersonService"
      class="org.springframework.remoting.rmi.RmiServiceExporter">
  <!-- RmiServiceExporter 对服务名没有特殊要求 -->
   <property name="serviceName">
    <value>LogPerson</value>
   </property>
   <property name="service">
    <ref bean="logPerson"/>
   </property>
   <property name="serviceInterface">
    <value>com.openv.spring.ILogPerson</value>
   </property>
  <!-- 避免与默认的RMI注册端口冲突,因此修改为1200 -->
   <property name="registryPort">
    <value>1200</value>
   </property>
</bean>

</beans>

5. 定义运行rmi服务的类: LogPersonRmiServer.java
package com.openv.spring;

import org.springframework.core.io.Resource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.beans.factory.BeanFactory;

import java.io.Serializable;

public class LogPersonRmiServer{
     public static void main(String[] args) {
         //初始化appcontextrmiserver.xml
         Resource sresource = new ClassPathResource("appcontextrmiserver.xml");
         BeanFactory sfactory = new XmlBeanFactory(sresource);

         //注册RMI
         sfactory.getBean("logPersonService");

     }
}

运行main函数,rmi服务就启动了。

下面写客户调用端的代码了。
大家从目录图中看一下,为了调试方便,我把服务端和客户端写在了一起。在实际的项目中,客户端的代码是不可能和服务器端在一起的,那样还叫什么远程调用呀,呵呵。在实际的项目中,我们应该把接口ILogPerson.java和POJO PersonVO.java 文件打成jar包给客户端引用即可,而实现是在服务器端完成。

下面我们可以在另外一台计算机(为了强调远程嘛,呵呵)上新建立一个客户端调用的工程。客户端很简单

1. 引入spring的依赖文件和 接口ILogPerson.java和POJO PersonVO.java 文件打成jar包

2. spring的依赖注入的文件 appcontextrmiclient.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
    "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="LogPerson"
   class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
   <property name="serviceUrl"><value>rmi://77.20.64.237:1200/LogPerson</value></property>
   <property name="serviceInterface"><value>com.openv.spring.ILogPerson</value></property>
</bean>
</beans>

3. 调用文件 LogPersonRmiClient.java
package com.openv.spring;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

public class LogPersonRmiClient {
     public static void main(String[] args) {
        //初始化appcontextrmiclient.xml
         Resource cresource = new ClassPathResource("appcontextrmiclient.xml");
         BeanFactory cfactory = new XmlBeanFactory(cresource);

        //实例化Person值对象
         PersonVO personVO = new PersonVO();
         personVO.setFirstname("Luo2");
         personVO.setLastname("Shifei");

        //获得RMI服务
         ILogPerson clientLog = (ILogPerson) cfactory.getBean("LogPerson");

        //调用RMI服务
         System.out.println("==>> " + clientLog.getPersion(personVO));
     }
}
客户端很简单的,呵呵。看看运行结果吧。

虽然简单,但是也有四五个文件,其实每个文件不是很复杂,只要耐着心思把其一个个写出来,就能成功,如果运行结果出来了,你对rmi的各种疑惑也就形如冰释了。我也搞了大半天才将其实现,愿能给参看的朋友一些提示。

经过spring的封装,rmi的复杂过程得到了很大的简化,基本变成了配置的过程,什么rmi手工注册和声成什么乱七八糟的文件都省略了。不过不能穿越防火墙,下面我们在介绍一种可以穿越防火墙的spring远程调用hissian。http://www.linuxso.com/architecture/11452.html

 

 

 

Spring 使用RMI
博客分类: Spring&EJB
SpringJava.netXML
Spring使用RMI非常简单,甚至比直接使用RMI还简单。

第一:首先定义接口:
Java代码 
import java.rmi.Remote;  
import java.rmi.RemoteException;  
 
import com.zakisoft.test.rmi.vo.User;  
 
public interface RmiUserService extends Remote{  
    User login(String username, String password) throws RemoteException;  
    void create(String username, String password) throws RemoteException;  

import java.rmi.Remote;
import java.rmi.RemoteException;

import com.zakisoft.test.rmi.vo.User;

public interface RmiUserService extends Remote{
 User login(String username, String password) throws RemoteException;
 void create(String username, String password) throws RemoteException;
}

Java代码 
import java.io.Serializable;  
 
public class User implements Serializable {  
 
    private static final long serialVersionUID = -3017748605531466285L;  
    private String username;  
    private String password;  
 
    public User(String username, String password) {  
 
        this.username = username;  
        this.password = password;  
 
    }  
 
    public String getUsername() {  
        return username;  
    }  
 
    public String getPassword() {  
        return password;  
    }  
 

import java.io.Serializable;

public class User implements Serializable {

 private static final long serialVersionUID = -3017748605531466285L;
 private String username;
 private String password;

 public User(String username, String password) {

  this.username = username;
  this.password = password;

 }

 public String getUsername() {
  return username;
 }

 public String getPassword() {
  return password;
 }

}


第二:实现接口
Java代码 
import java.net.MalformedURLException;  
import java.rmi.AlreadyBoundException;  
import java.rmi.Naming;  
import java.rmi.RemoteException;  
import java.rmi.registry.LocateRegistry;  
import java.rmi.server.UnicastRemoteObject;  
 
import com.zakisoft.test.rmi.server.UserService;  
import com.zakisoft.test.rmi.server.UserServiceImpl;  
import com.zakisoft.test.rmi.vo.User;  
 
public class RmiUserServiceImpl extends UnicastRemoteObject implements 
        RmiUserService {  
 
    UserService service = new UserServiceImpl();  
 
    public RmiUserServiceImpl() throws RemoteException {  
    }  
 
    private static final long serialVersionUID = -7138363701504022490L;  
 
    public void create(String username, String password) throws RemoteException {  
        service.create(username, password);  
    }  
 
    public User login(String username, String password) throws RemoteException {  
        return service.login(username, password);  
    }  
 
    public static void main(String[] args) throws RemoteException, MalformedURLException, AlreadyBoundException {  
        LocateRegistry.createRegistry(1099);  
        Naming.bind("rmi://localhost:1099/UserService", new RmiUserServiceImpl());  
        System.out.print("Service start");  
    }  
 

import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.server.UnicastRemoteObject;

import com.zakisoft.test.rmi.server.UserService;
import com.zakisoft.test.rmi.server.UserServiceImpl;
import com.zakisoft.test.rmi.vo.User;

public class RmiUserServiceImpl extends UnicastRemoteObject implements
  RmiUserService {

 UserService service = new UserServiceImpl();

 public RmiUserServiceImpl() throws RemoteException {
 }

 private static final long serialVersionUID = -7138363701504022490L;

 public void create(String username, String password) throws RemoteException {
  service.create(username, password);
 }

 public User login(String username, String password) throws RemoteException {
  return service.login(username, password);
 }

 public static void main(String[] args) throws RemoteException, MalformedURLException, AlreadyBoundException {
  LocateRegistry.createRegistry(1099);
  Naming.bind("rmi://localhost:1099/UserService", new RmiUserServiceImpl());
  System.out.print("Service start");
 }

}


第三:在Spring配置文件中配置RMI服务
Java代码 
<bean id="userService" class="com.zakisoft.test.rmi.server.UserServiceImpl"></bean>  
    <bean id="rmiService" class="org.springframework.remoting.rmi.RmiServiceExporter">  
        <property name="serviceName" value="UserService"/>  
        <property name="service" ref="userService"/>  
        <property name="serviceInterface" value="com.zakisoft.test.rmi.server.UserService"/>  
        <property name="registryPort" value="1099"/>  
    </bean> 

<bean id="userService" class="com.zakisoft.test.rmi.server.UserServiceImpl"></bean>
    <bean id="rmiService" class="org.springframework.remoting.rmi.RmiServiceExporter">
     <property name="serviceName" value="UserService"/>
     <property name="service" ref="userService"/>
     <property name="serviceInterface" value="com.zakisoft.test.rmi.server.UserService"/>
     <property name="registryPort" value="1099"/>
    </bean>


第四:启动RMI服务
Java代码 
public class SpringStartRmi {  
      
    public static void main(String[] args) {  
        new ClassPathXmlApplicationContext("zconfig.xml");  
    }  
 

public class SpringStartRmi {
 
 public static void main(String[] args) {
  new ClassPathXmlApplicationContext("zconfig.xml");
 }

}


第五:访问服务
Java代码 
import org.springframework.remoting.rmi.RmiProxyFactoryBean;  
 
import com.zakisoft.test.rmi.server.UserService;  
 
public class ClientSpringRmi {  
      
    public static void main(String[] args) {  
        RmiProxyFactoryBean factory = new RmiProxyFactoryBean();  
        factory.setServiceInterface(UserService.class);  
        factory.setServiceUrl("rmi://localhost:1099/UserService");  
        factory.afterPropertiesSet();  
          
        UserService userService = (UserService)factory.getObject();  
        userService.create("test", "test");  
        System.out.println(userService.login("new_user_01", "new_password_01"));      
        //userService.login("test", "test");  
    }  

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics