24.2 使用RMI暴露服务

使用Spring的RMI支持,你可以通过RMI基础架构透明地暴露你的服务。完成Spring的RMI设置后,你基本上具有类似于远程EJB配 置,除了没有对安全上下文传递和远程事务传递的标准支持。当使用RMI调用器时,Spring对这些额外的调用上下文提供了钩子,你可以在此插入安全框架 或者自定义的安全凭证。

24.2.1 使用RmiServiceExporter导出服务

使用RmiServiceExporter,我们可以把AccountService对象的接口暴露成RMI对象。可以使用RmiProxyFactoryBean或者在传统RMI服务中使用普通RMI来访问该接口。RmiServiceExporter明确支持使用RMI调用器暴露任何非RMI的服务。

当然,我们首先需要在Spring容器中设置我们的服务:

<bean id="accountService" class="example.AccountServiceImpl">
    <!-- any additional properties, maybe a DAO? -->
</bean>

下一步我们需要使用RmiServiceExporter来暴露我们的服务:

<bean class="org.springframework.remoting.rmi.RmiServiceExporter">
    <!-- does not necessarily have to be the same name as the bean to be exported -->
    <property name="serviceName" value="AccountService"/>
    <property name="service" ref="accountService"/>
    <property name="serviceInterface" value="example.AccountService"/>
    <!-- defaults to 1099 -->
    <property name="registryPort" value="1199"/>
</bean>

正如你所见,我们覆盖了RMI注册的端口号。通常你的应用服务器还维护一个RMI注册表,明智的做法是不要和它冲突。此外,服务名是用来绑定服务的。现在服务绑定在‘rmi://HOST:1199/AccountService’。我们将在客户端使用这个URL来链接到服务。

Note:servicePort属性被省略了(默认值为0).这表示在与服务通信时将使用匿名端口.

24.2.2 在客户端链接服务

我们的客户端是一个使用AccountService来管理account的简单对象:

public class SimpleObject {

    private AccountService accountService;

    public void setAccountService(AccountService accountService) {
        this.accountService = accountService;
    }

    // additional methods using the accountService

}

为了把服务链接到客户端上,我们将创建一个单独的Spring容器,包含这个简单对象和链接配置位的服务:

<bean class="example.SimpleObject">
    <property name="accountService" ref="accountService"/>
</bean>

<bean id="accountService" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
    <property name="serviceUrl" value="rmi://HOST:1199/AccountService"/>
    <property name="serviceInterface" value="example.AccountService"/>
</bean>

这就是我们为支持远程account服务在客户端所需要做的。Spring将透明地创建一个调用器并且通过RmiServiceExporter使得account服务支持远程服务。在客户端,我们用RmiProxyFactoryBean连接它。