Должны ли ссылки в службах, предоставляемых RMI, быть временными? - PullRequest
2 голосов
/ 16 ноября 2009

Я предоставляю некоторые сервисы, использующие RMI в Spring. Каждый сервис имеет зависимость от другого сервисного компонента, который выполняет реальную работу по обработке. Например:

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

Мой аккаунт RmiServiceImpl выглядит так:

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 Ответ

2 голосов
/ 16 ноября 2009

Может быть.

Вы могли бы определенно пометить поле accountService как переходное, что действительно помешало бы его сериализации и отправке через RMI (или, точнее, , если не удалось сериализовать и выдать исключение). Однако на этом этапе AccountRmiServiceImpl, восстановленный на другой стороне, будет иметь нулевое значение для accountService, что без каких-либо других изменений почти наверняка приведет к NullPointerException позже.

Если ваш AccountServiceImpl не сериализуем (в смысле Java), , но вы все еще можете создать его экземпляр на основе некоторой простой сериализуемой информации, то вам повезло. Вы можете реализовать сериализацию самостоятельно, используя методы writeObject / readObject или writeReplace / readResolve (см. Сериализуемый ).

Если экземпляры AccountServiceImpl не сериализуемы в каком-либо смысле слова (например, анонимный внутренний класс со встроенной логикой, а также ссылки на конечные локальные переменные во внешней области видимости), то нет способа отправить это через. Какой объект будет воссоздан на другой стороне? Если вы оказались в такой ситуации, вам нужно провести рефакторинг своего кода, чтобы сделать класс (ы) сериализуемыми.

...