RMI暴露服务中的引用应该是暂时的吗?

时间:2009-11-16 15:04:24

标签: java serialization rmi transient

我在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调用的客户端。有可能吗?

1 个答案:

答案 0 :(得分:2)

可能。

可以明确地将accountService字段标记为瞬态,这确实会阻止它被序列化并通过RMI发送(或者更确切地说,失败被序列化并抛出异常)。但是,此时在另一方重建的AccountRmiServiceImpl将为其accountService设置一个空值,没有任何其他更改几乎肯定会导致NullPointerException以后。

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

如果的AccountServiceImpl是不是在字(例如,具有内联逻辑匿名内部类以及在其外部范围最终本地变量的参考文献)中的任感serialisable,那么就没有办法发送此实例跨越。在另一边会重建什么样的物体?如果您遇到这种情况,则需要重构代码以使类可序列化。