RMI 公开服务中的引用应该是暂时的吗?

发布于 2024-08-11 06:41:42 字数 1325 浏览 3 评论 0 原文

我正在 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;
    }
}

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

I'm exposing some services using RMI on Spring. Every service has a dependency to other service bean which does the real processing job. For example:

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

My AccountRmiServiceImpl looks like this:

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

    private AccountService accountService;

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

My question is: could AccountServiceImpl be created without implementing the Serializable marker interface? If it is a case, then its reference in AccountRmiServiceImpl should be made transient. This means that it would not be serialized and transfered to the client where the RMI invocation is being made. Is it possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一江春梦 2024-08-18 06:41:42

或许。

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

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

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

Maybe.

You could definitely mark the accountService field as transient, which would indeed stop it from being serialised and sent over RMI (or more accurately, failing to be serialised and throwing an exception). However, at this point the AccountRmiServiceImpl that's reconstructed on the other side will have a null value for its accountService, which without any other changes would almost certainly lead to a NullPointerException later.

If your AccountServiceImpl is not serialisable (in the Java sense), but you are still able to create an instance of it based on some simple serialisable information, then you're in luck. You can implement the serialisation yourself using the writeObject/readObject or writeReplace/readResolve methods (see Serializable for details).

If instances of AccountServiceImpl are not serialisable in any sense of the word (e.g. an anonymous inner class with inline logic as well as references to final local variables in its outer scope), then there's no way to send this across. What kind of object would be recreated on the other side? If this is the situation you find yourself in, you'd need to refactor your code to make the class(es) serialisable.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文