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

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

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

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
7
0
1 992
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

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

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

@Hugo относительно threadlocal:

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

  1. Общий поток (соединения с сервером и т. д.) Проблематичен. Однако эту проблему можно решить, уделив особое внимание этим потокам (все они находятся под моим контролем и в значительной степени изолированы от устаревшего кода).
  2. Поток EDT является общим для всех апплетов. Мне не удалось найти способ принудительно создать новый поток EDT для каждого апплета. Это означает, что локальный поток для EDT будет совместно использоваться всеми апплетами. Я понятия не имею, как решить эту проблему. Предложения?

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

Tom Hawtin - tackline 11.10.2008 05:10
Ответ принят как подходящий

Синглтоны - это зло, чего вы ждете? ;)

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

Другие хаки:

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

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

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

Это (безусловно) лучшая коллекция идей, которые я видел по этому поводу. Мне особенно нравится «выдвинуть настраиваемую очередь событий» - и я собираюсь ее попробовать.

Ran Biron 17.09.2008 08:56

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