Spring RMI 配置

lxpandsq 2012-05-19

1 RMI的概念

Java Remote Method Invocation (RMI) is Java's remote procedure call (RPC) mechanism. RMI allows you to write distributed objects using Java.

RMI调用的过程,我的理解大致如下:

  • 客户端和服务器端约定好要用于远程调用的方法的接口(包括方法名和输入输出参数)。
  • 服务器端将远程服务绑定到某个端口,进行TCP/IP监听(例如监听地址为rmi://127.0.0.1:1099)。
  • 客户端与服务器建立TCP/IP连接(当然事先要知道服务器端的监听地址),按照接口声明的方法发送数据(可序列化的Java对象)以及要调用的服务名、方法名等。
  • 服务器端将接收到的数据(字节流)反序列化,得到要调用的方法和参数信息;然后服务器端进行本地计算(方法调用)。
  • 服务器端将计算的结果(可序列化的Java对象)发送给客户端。
  • 客户端从接收到的返回数据(字节流)中进行反序列化,得到运算结果。
  • 客户端断开与服务器端的TCP/IP连接,远程调用结束。

2 Spring 配置

Spring --RMI远程方法调用

服务器端配置

(1)首先新建一个j2se项目,添加相关jar

commons-logging-1.1.1.jar ----- 打印日志

spring-2.5.6.SEC02.jar -----解决 异常:java.lang.NoClassDefFoundError: org/aopalliance/aop/Advice

spring-aop-2.5.6.jar

spring-beans-2.5.6.SEC02.jar

spring-context-2.5.6.SEC02.jar

spring-context-support-2.5.6.SEC02.jar

spring-core-2.5.6.SEC02.jar

(2)新建一个接口如下:

public interface ILogPerson {

public String getPersion();

public void setPersion(String info);

}

(3)接口实现类:

public class LogPerson implements ILogPerson {

private String delegateinfo;

@Override

public String getPersion() {

return delegateinfo;

}

public void setPersion(String info) {

this.delegateinfo=info;

}

}

(4)添加Spring配置文件 appcontextrmiserver.xml(名字自定义)

<bean id="logPersonService" class="org.springframework.remoting.rmi.RmiServiceExporter">

<property name="serviceName">

<value>LogPerson</value>

</property>

<property name="serviceInterface">

<value>com.test.rmi.ILogPerson</value>

</property>

<property name="registryPort">

<value>1200</value>

</property>

</bean>

(5)注册服务(其实就是获取bean)

可以新建一个测试类,在main方法中获取bean信息

public static void main(String[] args) {

//BeanFactory factory=new XmlBeanFactory(new FileSystemResource("appcontextrmiserver.xml"));

//ApplicationContext context = new ClassPathXmlApplicationContext("appcontextrmiserver.xml");

Resource resource = new ClassPathResource("appcontextrmiserver.xml");

BeanFactory factory = new XmlBeanFactory(resource);

factory.getBean("logPersonService");

}

(6)执行main方法,如果看到一下信息 就表示注册成功!

服务器端注册成功::信息: Binding service 'LogPerson' to RMI registry: RegistryImpl[UnicastServerRef [liveRef: [endpoint:

[10.13.122.200:1200](local),objID:[0:0:0, 0]]]]

10.13.122.200 就是当前服务器的ip地址,1200是在xml中配置的注册端口号

客户端调用配置

(1)新建一个j2se项目

(2)将服务器端的接口和接口实现类打成jar文件(或者直接将服务器端接口和接口实现类直接拷到应用中),

添加到应用中,然后添加相关Spring的jar

(3)添加Spring配置

<bean id="LogPerson"class="org.springframework.remoting.rmi.RmiProxyFactoryBean">

<property name="serviceUrl">

<value>rmi://10.13.122.193:1200/LogPerson</value>

//对应服务器端IP地址和配置的端口号,LogPerson指服务器端配置的serviceName的value值

</property>

<property name="serviceInterface">

<value>com.test.rmi.ILogPerson</value>

//对应服务器端配置的"serviceInterface"的value值

</property>

</bean>

(4)添加测试类

public class LogPersonRmiClient {

public static void main(String[] args) {

ApplicationContext context = new ClassPathXmlApplicationContext("appcontextrmiserver.xml");

ILogPerson clientLog = (ILogPerson)context.getBean("LogPerson");

clientLog.setPersion("RMI客户端调用!");

}

}

经常出现的异常:

(1)写一个rmi客户端程序,你可能会收到如标题这样的异常。这个问题其实是由rmi服务器端程序造成的。

客户端程序向服务端请求一个对象的时候,返回的stub对象里面包含了服务器的hostname,客户端的后续操作根据这个hostname来连接服务

器端。要想知道这个hostname具体是什么值可以在服务器端bash中打入指令:

hostname -i

如果返回的是127.0.0.1,那么你的客户端肯定会抛如标题的异常了。

解决这个问题有两个方式:

1 修改/etc/hosts

找到127.0.0.1 hostxxxxx这样的字样。把127.0.0.1改成真实的,可供其他机器连接的ip。

这样客户端就能得到真实的ip了

相关推荐

Iamlonely / 0评论 2013-01-23