Wie kann ich feststellen, in welchem ​​Java-Applet-Kontext es ausgeführt wird, ohne eine ID zu übergeben?

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

  •  08-06-2019
  •  | 
  •  

Frage

Ich bin Teil eines Teams, das ein ziemlich großes Swing-Java-Applet entwickelt.Der Großteil unseres Codes ist veraltet und es gibt jede Menge Singleton-Referenzen.Wir haben sie alle in einem einzigen „Application Context“-Singleton zusammengefasst.Jetzt müssen wir eine Möglichkeit schaffen, den gemeinsamen Kontext (gemeinsam für alle derzeit angezeigten Applets) und den nicht gemeinsam genutzten Kontext (spezifisch für jedes derzeit angezeigte Applet) zu trennen.

Wir haben jedoch nicht an jedem Standort, der den Singleton aufruft, eine ID, und wir möchten die ID auch nicht an alle Standorte weitergeben.Wie lässt sich am einfachsten feststellen, in welchem ​​Applet-Kontext wir ausgeführt werden?(Ich habe versucht, mit Klassenladern, Thread-Gruppen, Thread-IDs herumzuspielen ...Bisher konnte ich nichts finden, was es mir ermöglichen würde, den Ursprung des Anrufs zu identifizieren.

War es hilfreich?

Lösung

Singletons sind böse, was erwartest du?;)

Der vielleicht umfassendste Ansatz wäre, den Großteil des Applets in einen anderen Klassenlader zu laden (verwenden Sie java.net.URLClassLoader.newInstance).Verwenden Sie dann eine WeakHashMap, um den Klassenlader einem Applet zuzuordnen.Wenn Sie den größten Teil des Codes in einen gemeinsamen Klassenlader (als übergeordnetes Element jedes Applet-Klassenladers) und in die normale Applet-Codebasis aufteilen könnten, wäre das schneller, aber mit mehr Arbeit verbunden.

Andere Hacks:

Wenn Sie Zugriff auf eine beliebige Komponente haben, können Sie Component.getParent wiederholt oder SwingUtilities.getRoot verwenden.

Wenn Sie sich in einem Thread pro Applet-Instanz befinden, können Sie einen ThreadLocal einrichten.

Vom EDT aus können Sie das aktuelle Ereignis aus der Warteschlange lesen (java.awt.EventQueue.getCurrentEvent()) und möglicherweise eine Komponente daraus finden.Alternativ können Sie eine EventQueue mit einer überschriebenen „dispatchEvent“-Methode pushen.

Andere Tipps

Wenn ich Sie richtig verstehe, besteht die Idee darin, für jedes Aufruferobjekt oder jeden „Kontext“ ein anderes „Singleton“-Objekt zu erhalten.Sie können beispielsweise eine Thread-lokale globale Variable erstellen, in die Sie die ID des aktuellen Kontexts schreiben.(Dies kann mit AOP erfolgen.) Anschließend wird im Singleton-Getter die Kontext-ID vom Thread-Local abgerufen, um sie als Schlüssel für die richtige „Singleton“-Instanz für den aufrufenden Kontext zu verwenden.

Was AOP betrifft, sollte es kein Problem sein, es in Applets zu verwenden, da abhängig von Ihren Point-Cuts die Hinweise zur Kompilierungszeit gewebt werden und den Laufzeitabhängigkeiten ein JAR hinzugefügt wird.Daher sollten zur Laufzeit keine besonderen Hinweise auf AOP vorhanden sein.

@Hugo bezüglich threadlocal:

Ich habe über diese Lösung nachgedacht.Bei Experimenten habe ich jedoch zwei Probleme bei diesem Ansatz festgestellt:

  1. Gemeinsam genutzte Threads (Serververbindungen usw.) sind problematisch.Dies kann jedoch gelöst werden, indem man diesen Threads besondere Aufmerksamkeit schenkt (sie stehen alle unter meiner Kontrolle und sind weitgehend vom Legacy-Code isoliert).
  2. Der EDT-Thread wird von allen Applets gemeinsam genutzt.Ich konnte keine Möglichkeit finden, die Erstellung eines neuen EDT-Threads für jedes Applet zu erzwingen.Dies bedeutet, dass der Threadlocal für den EDT von allen Applets gemeinsam genutzt wird.Ich habe keine Ahnung, wie ich dieses Problem lösen soll.Vorschläge?
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top