使用Spring简化RMI编程到底简化了什么

今天在重看Spring in Action,看到远程调用这一章。讲到了Spring简化RMI的开发。说实话,在我的工作中还从来没有编写过RMI的代码,关于RMI也只是当初学习的时候看过一点点,现在早就忘记了。因此又把RMI翻出来看了看。

编写RMI客户-服务器程序包括以下的基本步骤:

1. 定义远程接口

2. 实现远程接口

3. 生成stub 和 skeleton (V1.2不需要skeleton)

4. 启动注册表并注册对象

5. 编写使用远程对象的客户



其中1-4是服务器端要进行的工作,5是客户端要进行的工作。下面是一个很简单的RMI的示例程序:

1. 定义远程接口
import java.rmi.Remote;

public interface HelloInterface extends Remote {
	public String sayHello() throws java.rmi.RemoteException;
}


2. 实现远程接口
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.Calendar;

public class HelloServer extends UnicastRemoteObject implements HelloInterface {

	public HelloServer() throws RemoteException {
		super();
	}

	@Override
	public String sayHello() throws RemoteException {
		String greeting = null;
		int hourOfDay = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
		if (hourOfDay >= 20){
			greeting = "Good evening.";
		} else if (hourOfDay >= 12){
			greeting = "Good afternoon.";
		} else {
			greeting = "Good Morning";
		}
		
		return greeting;
	}

}


3. 生成stub和skeleton
使用Java提供的命令行来生成
rmic -d HelloServer

4. 启动注册表并注册对象
import java.rmi.Naming;
import java.rmi.registry.LocateRegistry;

public class HelloServerRegistor {
	public static void main(String[] args){
		try{
			HelloServer server = new HelloServer();
			System.out.println("HelloServer is created: ");
			LocateRegistry.createRegistry(1099);
			Naming.rebind("/HelloServer", server);
			System.out.println("HelloServer is bound.");
		} catch (Exception e){
			e.printStackTrace();
		}
	}
}


5. 编写客户端程序
import java.rmi.Naming;
import java.rmi.RMISecurityManager;

import ServerSide.HelloInterface;

public class HelloClient {
	public static void main(String[] args){
		if (System.getSecurityManager() == null){
			System.setSecurityManager(new RMISecurityManager());
		}
		
		try{
			HelloInterface server = (HelloInterface)Naming.lookup("/HelloServer");
			System.out.println(server.sayHello());
		} catch (Exception e){
			e.printStackTrace();
		}
	}
}






上面是我们直接使用RMI时需要手动完成的工作,注意因为我的实例代码都是运行在同一台机器上的,在RMI的URL中没有指定主机名称。

下面来看我们使用Spring会简化哪些工作。
从客户端的角度来看:
假设已经有服务器提供了HelloServer服务,我们只需要调用该服务。Spring使用RmiProxyFactoryBean来创建指向RMI服务的代理。

引用

<bean id = "HelloServer" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
    <property name="serviceUrl">
        <value> /HelloServer</value>
    </property>
    <property name="serviceInterface">
        <value>HelloInterface</value>
    </property>
</bean>




要调用HelloServer的程序就可以使用Spring定义的这个HelloServer bean来调用RMI了。

抛开Spring所提倡的IoC等,对于客户端来说,其实没有简化多少东西。另外Spring框架在这里会处理所有的RemoteException并将其封装成RuntimeException抛出,因此在客户端程序中不是必须要写RemoteException的处理代码。

从服务器端的角度来看
1.我们仍然需要定义接口,但是不需要继承Remote接口。
2.当然也需要实现该接口。
3.将实现类在Spring中配置为bean
引用

<bean id="HelloServerImpl" class="HelloServer">
  ......
</bean>

4.使用Spring的RmiServiceExporter将bean输出成一个RMI服务
引用

<bean class="org.spring.framework.remoting.rmi.RmiServiceExporter">
    <property name="service">
        <ref bean="HelloServerImpl"/>
    </property>
    <property name="serviceName">
        <value>HelloServer</value>
    </property>
    <property name="serviceInterface">
        <value>HelloInterface</value>
    </property>
</bean>

对于服务器端来说,原来的步骤3(生成stup和skeleton)与步骤4(启动注册表并注册RMI服务)没有了,取而代之的是配置了RmiServiceExporter类型的bean。但是从实际的工作量上来看,并没有简化多少。

那么使用Spring进行RMI编程到底简化了什么呢?我的理解是,由于Spring封装了RMI的具体实现,所以简化的实际上是对RMI编程知识的要求。

你可能感兴趣的:(java,spring,编程,工作,bean)