Come posso identificare in quale contesto dell'applet Java è in esecuzione senza passare un ID?

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

  •  08-06-2019
  •  | 
  •  

Domanda

Faccio parte di un team che sviluppa un'applet Swing Java piuttosto grande.La maggior parte del nostro codice è legacy e ci sono tonnellate di riferimenti singleton.Li abbiamo raggruppati tutti in un singolo singleton "Contesto dell'applicazione".Ciò di cui ora abbiamo bisogno è creare un modo per separare il contesto condiviso (condiviso tra tutte le applet attualmente visualizzate) e il contesto non condiviso (specifico per ciascuna applet attualmente visualizzata).

Tuttavia, non abbiamo un ID in ciascuna delle posizioni che chiamano il singleton, né vogliamo propagare l'ID a tutte le posizioni.Qual è il modo più semplice per identificare in quale contesto dell'applet stiamo eseguendo?(Ho provato a fare confusione con i classloader, i gruppi di thread, gli ID dei thread...finora non sono riuscito a trovare nulla che mi permetta di identificare l'origine della chiamata).

È stato utile?

Soluzione

I single sono cattivi, cosa ti aspetti?;)

Forse l'approccio più completo sarebbe caricare la maggior parte dell'applet in un caricatore di classi diverso (utilizzare java.net.URLClassLoader.newInstance).Quindi utilizzare WeakHashMap per associare il caricatore di classi a un'applet.Se potessi dividere la maggior parte del codice in un caricatore di classi comune (come genitore di ciascun caricatore di classi per applet) e nella base di codice dell'applet normale, sarebbe più veloce ma richiederebbe più lavoro.

Altri hack:

Se hai accesso a qualsiasi componente, puoi utilizzare Component.getParent ripetutamente o SwingUtilities.getRoot.

Se ti trovi in ​​un thread di istanza per applet, puoi impostare un ThreadLocal.

Dall'EDT, puoi leggere l'evento corrente dalla coda (java.awt.EventQueue.getCurrentEvent()) ed eventualmente trovare un componente da quello.In alternativa, invia un EventQueue con un metodo dispatchEvent sovrascritto.

Altri suggerimenti

Se ho capito bene, l'idea è quella di ottenere un oggetto "singleton" diverso per ciascun oggetto chiamante o "contesto".Una cosa che puoi fare è creare una variabile globale thread-locale in cui scrivi l'ID del contesto corrente.(Questo può essere fatto con AOP.) Quindi nel getter singleton, l'ID del contesto viene recuperato dal thread locale da utilizzare come chiave per l'istanza "singleton" corretta per il contesto chiamante.

Per quanto riguarda AOP non dovrebbero esserci problemi ad usarlo nelle applet poiché, a seconda dei tagli di punti, i consigli vengono intrecciati in fase di compilazione e un JAR viene aggiunto alle dipendenze di runtime.Pertanto, in fase di esecuzione non dovrebbe rimanere alcuna prova speciale dell'AOP.

@Hugo riguardo a threadlocal:

Ho pensato a quella soluzione.Tuttavia, dagli esperimenti ho riscontrato due problemi con questo approccio:

  1. I thread condivisi (connessioni al server, ecc.) sono problematici.Questo può essere risolto prestando particolare attenzione a questi thread (sono tutti sotto il mio controllo e sono praticamente isolati dal codice legacy).
  2. Il thread EDT è condiviso tra tutte le applet.Non sono riuscito a trovare un modo per forzare la creazione di un nuovo thread EDT per ciascuna applet.Ciò significa che il threadlocale per l'EDT verrebbe condiviso tra le applet.Questo non ho idea di come risolverlo.Suggerimenti?
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top