首页 > 代码库 > 【Spring】几种RPC模型的使用与比较——RMI

【Spring】几种RPC模型的使用与比较——RMI

上回写到<基于JMS的RPC>时使用到了:
·org.springframework.jms.remoting.JmsInvokerServiceExporter
·org.springframework.jms.remoting.JmsInvokerProxyFactoryBean

spring在实现RPC的几种方式上都提供了风格一致的支持。
在这里我打算把几种RPC模型记录下来并作比较。

·RMI
·Hessian/Burlap
·HTTP Invoker
·JAX-WS


先从最基本的RMI开始。
RMI相关的API早在JDK1.1时就有了,我在这里简单描述一下RMI的原生实现(代码可以从别的地方参考)。
·声明一个远程接口,接口必须继承
java.rmi.Remote,方法需要抛出java.rmi.RemoteException
·为远程接口提供实现,实现类需要继承UnicastRemoteObject。
·或者可以使用rmi相关命令创建skelton和stub。
·启动一个RMI注册表并注册。


如果是spring实现RMI,方法会简单很多。
我们只需要用到两个类:
·
org.springframework.remoting.rmi.RmiServiceExporter
·org.springframework.remoting.rmi.RmiProxyFactoryBean

我简单定义一下接口和实现类:

package pac.testcase.ws;
public interface MyService {
    public boolean inviteMeIn();
    public String welcome();
}
package pac.testcase.ws.impl;
import pac.testcase.ws.MyService;
public class MyServiceImpl implements MyService{
    public boolean inviteMeIn() {
        return true;
    }
    public String welcome() {
        return "Everybody is welcome!!";
    }
}

简简单单,不需要继承其他任何东西,非常pojo。


下面是spring相关配置:

<bean id="myService" class="pac.testcase.ws.impl.MyServiceImpl" />
<bean class="org.springframework.remoting.rmi.RmiServiceExporter"
    p:service-ref="myService"
    p:serviceName="welcomeService"
    p:serviceInterface="pac.testcase.ws.MyService"
/>

将我们的pojo导出为RMI服务,在这里我采用默认配置。
地址在默认情况时如下:

/**
 * Set the host of the registry for the exported RMI service,
 * i.e. {@code rmi://HOST:port/name}
 * <p>Default is localhost.
 */
public void setRegistryHost(String registryHost) {
    this.registryHost = registryHost;
}
/**
 * Set the port of the registry for the exported RMI service,
 * i.e. {@code rmi://host:PORT/name}
 * <p>Default is {@code Registry.REGISTRY_PORT} (1099).
 * @see java.rmi.registry.Registry#REGISTRY_PORT
 */
public void setRegistryPort(int registryPort) {
    this.registryPort = registryPort;
}


客户端方面使用RmiProxyFactoryBean,被代理的服务就像一个简单的bean一样:

<bean id="clientSideService" class="org.springframework.remoting.rmi.RmiProxyFactoryBean"
    p:serviceUrl="rmi://localhost:1099/welcomeService"
    p:serviceInterface="pac.test.RemoteService"
/>


配置中的pac.test.RemoteService就是那个简单的bean,根据客户端的需要,在这里重新定义一下。

package pac.test;
public interface RemoteService {
    public String welcome();
}


这样就可以在服务端调用了,不用做什么Naming.lookup(serviceUrl)之类的操作,一切都想调用本地那样。

ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
RemoteService service = (RemoteService)context.getBean("clientSideService");
System.out.println(service.welcome());


RMI虽然简单高效,但使用RMI会存在一个问题(其实还有别的问题,比如防火墙什么的)——RMI使用的是Java的序列化机制,序列化你懂的,他有版本问题。
于是在下一篇我打算试试
Hessian/Burlap


本文出自 “Map.get(X)=new Object()” 博客,请务必保留此出处http://runtime.blog.51cto.com/7711135/1405562