Лучший способ сериализации и десериализации объекта без потери его слушателей?

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

Каким будет самый безопасный и лучший способ автоматически перерегистрировать слушателей после десериализации объекта? Есть ли здесь хороший шаблон дизайна?

Это немного расплывчато ... возможно, вы захотите дать более подробную информацию ... каковы обстоятельства, при которых он сериализуется / десериализуется ...

Mike Stone 25.09.2008 11:16

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

Rob Cooper 25.09.2008 11:48
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
7
2
2 420
5

Ответы 5

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

Я бы построил независимую структуру событий, что означает, что производитель событий не будет напрямую привязан к потребителю событий. Он может состоять из EventManager, EventProducer и EventListener, работающих вместе с семантикой публикации / подписки.

  1. При запуске системы (или при первом использовании) создается EventManager.
  2. EventListener регистрируется для получения событий определенного типа.
  3. EventProducer создает события и публикует их в EventManager.
    public interface EventManager {
        public void postEvent(Event event);
        public void addListener(Class eventType, EventListener listener);
    }

    public interface EventListener {
        public void handleEvent(Event event);
    }

Таким образом, когда вы сериализуете производителя, EventManager по-прежнему поддерживает список подписанных слушателей. когда объект десериализован, он все еще может отправлять события в EventManager.

В общем, я не нашел для этого никакого полезного шаблона. Но сочетание нескольких будет нормально :). Вопрос в том, как вы справляетесь с десериализацией? При использовании стандартного способа вы можете ввести механизм поиска, который будет использоваться для поиска локальных слушателей и повторной привязки их к только что десериализованному экземпляру. Если у вас есть собственный десериализатор, путь будет проще. Просто десериализуйте объект и зарегистрируйте локальных слушателей. Десериализатор может выступать в качестве прослушивателя прокси, если это возможно. Как сказал Панайотис, введение некоторой несвязанной модели также должно быть полезным. Точное решение зависит от вашей реальной потребности, но не забудьте его ЦЕЛОВАТЬ.

Используйте реестр, в котором зарегистрированы и ваш издатель, и подписчики. Как было опубликовано Корросом, в стране OSGI это называется шаблоном доски.

Если вы реализуете readObject (), вы можете реконструировать переходное состояние как часть десериализации. Вы должны рассматривать десериализацию как построение объекта (потому что это так).

   private void readObject(ObjectInputStream in) 
       throws ClassNotFoundException, IOException {
     // do normal serialization first!
     in.defaultReadObject();

     // put code here that can somehow reconstruct your listeners
     // presumably you have someplace you can look them up
  }

Другие вопросы по теме