Как я могу определить, в каком контексте Java-апплета запущен, не передавая идентификатор?

StackOverflow https://stackoverflow.com/questions/7269

  •  08-06-2019
  •  | 
  •  

Вопрос

Я являюсь частью команды, которая разрабатывает довольно большой Java-апплет Swing.Большая часть нашего кода является устаревшей, и в нем содержится множество ссылок на синглтоны.Мы объединили их все в один синглтон "Контекст приложения".Теперь нам нужно создать какой-то способ разделения общего контекста (общего для всех отображаемых в данный момент апплетов) и необщего контекста (специфичного для каждого отображаемого в данный момент апплета).

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

Это было полезно?

Решение

Одиночки - это зло, чего ты ожидал?;)

Возможно, наиболее всеобъемлющим подходом было бы загрузить основную часть апплета в другой загрузчик классов (используйте java.net.URLClassLoader.newInstance).Затем используйте WeakHashMap, чтобы связать загрузчик классов с апплетом.Если бы вы могли разделить большую часть кода на общий загрузчик классов (как родительский для каждого загрузчика классов для каждого апплета) и на обычную кодовую базу апплета, это было бы быстрее, но и больше работы.

Другие хаки:

Если у вас есть доступ к какому-либо компоненту, вы можете повторно использовать Component.getParent или SwingUtilities.getRoot.

Если вы находитесь в потоке для каждого экземпляра апплета, то вы можете настроить ThreadLocal.

Из EDT вы можете прочитать текущее событие из очереди (java.awt.EventQueue.getCurrentEvent()) и, возможно, найти компонент из этого.В качестве альтернативы отправьте EventQueue с переопределенным методом dispatchEvent.

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

Если я вас правильно понял, идея состоит в том, чтобы получить другой "одноэлементный" объект для каждого вызывающего объекта или "контекста".Одна вещь, которую вы можете сделать, это создать локальную глобальную переменную потока, в которую вы записываете идентификатор текущего контекста.(Это можно сделать с помощью AOP.) Затем в одноэлементном получателе идентификатор контекста извлекается из локального потока для использования в качестве ключа к правильному экземпляру "singleton" для вызывающего контекста.

Что касается AOP, не должно возникнуть проблем с его использованием в апплетах, поскольку, в зависимости от ваших пожеланий, советы сплетаются во время компиляции, а JAR добавляется к зависимостям времени выполнения.Следовательно, во время выполнения не должно оставаться никаких особых доказательств AOP.

@Хьюго относительно threadlocal:

Я думал об этом решении.Однако в ходе экспериментов я обнаружил две проблемы, связанные с таким подходом:

  1. Общий поток (подключения к серверу и т.д.) Является проблематичным.Однако это можно решить, уделив особое внимание этим потокам (все они находятся под моим контролем и в значительной степени изолированы от устаревшего кода).
  2. Поток EDT является общим для всех апплетов.Мне не удалось найти способ принудительно создавать новый поток EDT для каждого апплета.Это означает, что threadlocal для EDT будет общим для всех апплетов.Эту проблему я понятия не имею, как решить.Предложения?
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top