Как сохранить идентичность объекта на разных виртуальных машинах - PullRequest
3 голосов
/ 08 июня 2010

Чтобы быть конкретным, позвольте мне проиллюстрировать вопрос с примером Spring http-remoting.

Предположим, у нас есть такая реализация простого интерфейса:

public SearchServiceImpl implements SearchService {
    public SearchJdo processSearch(SearchJdo search) {
        search.name = "a funky name";
        return search;
    }
}

SearchJdo сам по себе простой POJO.

Теперь, когда мы вызываем метод из клиента через http-remoting (механизм Spring для вызова удаленных объектов, очень похожий на EJB, который использует сериализацию), мы получим:

public class HTTPClient {
    public static void main(final String[] arguments) {
        final ApplicationContext context = new ClassPathXmlApplicationContext(
            "spring-http-client-config.xml");
        final SearchService searchService =
            (SearchService) context.getBean("searchService");

        SearchJdo search = new SearchJdo();
        search.name = "myName"; 
        // this method actually returns the same object it gets as an argument
        SearchJdo search2 = searchService.processSearch(search);
        System.out.println(search == search2); // prints "false"
    }
}

Проблема в том, что объекты поиска отличаются из-за сериализации, хотя с логической точки зрения они одинаковы.

Вопрос заключается в том, существует ли какая-либо техника, которая позволяет поддерживать или эмулировать идентичность объекта в виртуальных машинах.

Ответы [ 3 ]

1 голос
/ 08 июня 2010

Вы сказали это - идентичность объекта отличается от логического равенства.

  • идентификатор объекта сравнивается с ==
  • логическое равенство сравнивается с .equals(..)

Так что переопределите метод equals(), и все будет хорошо. Не забудьте переопределить hashCode(), основываясь на тех же полях. Используйте вашу IDE, чтобы сгенерировать эти 2 метода для вас.

( Кластеризация Teracotta VM позволяет обмениваться объектами между виртуальными машинами, но это не подходит для вашего случая.)

1 голос
/ 08 июня 2010

ИМХО, попытка сохранить равенство идентичности объекта между виртуальными машинами - проигрышное предложение. Насколько я знаю, спецификация языка не требует, чтобы виртуальная машина поддерживала это, поэтому вы будете ограничены в возможностях, если вы действительно хотите быть переносимым.

Могу ли я спросить, почему вы не используете какой-то уникальный идентификатор, который вы предоставляете сами? Идентификаторы GUID Java, хотя и дорогие, являются сериализуемыми.

0 голосов
/ 25 ноября 2010

Я сделал это один раз, но я не совсем уверен, что это правильный подход:

Каждый пользователь имел имя пользователя, идентификатор сеанса, роли и дату входа в систему, прикрепленные к объекту пользователя. Каждый раз, когда я входил в виртуальную машину, система загружала объект User в память; Я бы также вернул объект пользователя в приложение.

Если бы мне нужно было выполнить действие на сервере приложений, я бы отправил объект пользователя в качестве аргумента. Если на виртуальную машину загружен пользователь с тем же идентификатором сеанса, то он будет использовать объект, хранящийся на виртуальной машине, для определения назначенных ролей. В противном случае приложение сможет изменять роли пользователя и не будет защищено.

Если приложение должно было изменить сервер приложений, оно отправляет объект пользователя на новый сервер, и новый сервер не сможет найти пользователя в своих записях.

ЗДЕСЬ СЕКРЕТ: Идентификатор сеанса создается с хэшированием имени пользователя, даты входа в систему и секретного пароля, общего для всех серверов.

Как только новый сервер обнаружит, что идентификатор сеанса согласован, он загрузит роли из базы данных в качестве надежного источника информации.

Извините, если я не смог написать это раньше, но надеюсь, что это кому-нибудь поможет.

...