2

我在 Spring 上使用 RMI 公开了一些服务。每个服务都依赖于执行实际处理工作的其他服务 bean。例如:

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

<bean id="rmiAccount" class="example.AccountRmiServiceImpl"/>

<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>

我的 AccountRmiServiceImpl 看起来像这样:

public class AccountRmiServiceImpl implements AccountRmiService {
    private static final long serialVersionUID = -8839362521253363446L;

    private AccountService accountService;

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

我的问题是:可以AccountServiceImpl在不实现Serializable标记接口的情况下创建吗?如果是这种情况,那么它的引用AccountRmiServiceImpl应该是暂时的。这意味着它不会被序列化并传输到进行 RMI 调用的客户端。是否可以?

4

1 回答 1

1

也许。

您绝对可以将该字段标记accountService为瞬态,这确实会阻止它被序列化并通过 RMI 发送(或者更准确地说,无法序列化并引发异常)。但是,此时AccountRmiServiceImpl在另一端重建的那将为其 accountService 具有空值,如果没有任何其他更改,几乎肯定会导致NullPointerException稍后发生。

如果您AccountServiceImpl不是可序列化的(在 Java 意义上),您仍然能够基于一些简单的可序列化信息创建它的实例,那么您很幸运。您可以使用 writeObject/readObject 或 writeReplace/readResolve 方法自己实现序列化(有关详细信息,请参阅Serializable)。

如果 的实例AccountServiceImpl在任何意义上都不可序列化(例如,具有内联逻辑的匿名内部类以及在其外部范围内对最终局部变量的引用),那么就无法发送它。另一边会重新创建什么样的对象?如果这是您发现自己所处的情况,则需要重构代码以使类可序列化。

于 2009-11-16T15:45:20.017 回答