Como posso identificar em qual contexto do Java Applet está sendo executado sem passar um ID?

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

  •  08-06-2019
  •  | 
  •  

Pergunta

Faço parte de uma equipe que desenvolve um grande miniaplicativo Swing Java.A maior parte do nosso código é legado e há inúmeras referências singleton.Reunimos todos eles em um único singleton "Contexto de aplicativo".O que precisamos agora é criar alguma maneira de separar o contexto compartilhado (compartilhado entre todos os miniaplicativos exibidos atualmente) e o contexto não compartilhado (específico para cada miniaplicativo exibido atualmente).

Entretanto, não temos um ID em cada um dos locais que chamam o singleton, nem queremos propagar o ID para todos os locais.Qual é a maneira mais fácil de identificar em qual contexto de miniaplicativo estamos executando?(Eu tentei mexer com classloaders, grupos de threads, IDs de threads...até agora não consegui encontrar nada que me permitisse identificar a origem da chamada).

Foi útil?

Solução

Singletons são maus, o que você esperava?;)

Talvez a abordagem mais abrangente seria carregar a maior parte do miniaplicativo em um carregador de classes diferente (use java.net.URLClassLoader.newInstance).Em seguida, use um WeakHashMap para associar o carregador de classes a um miniaplicativo.Se você pudesse dividir a maior parte do código em um carregador de classes comum (como pai de cada carregador de classes por miniaplicativo) e na base de código do miniaplicativo normal, isso seria mais rápido, mas mais trabalhoso.

Outros truques:

Se você tiver acesso a qualquer componente, poderá usar Component.getParent repetidamente ou SwingUtilities.getRoot.

Se você estiver em um thread de instância por miniaplicativo, poderá configurar um ThreadLocal.

No EDT, você pode ler o evento atual da fila (java.awt.EventQueue.getCurrentEvent()) e possivelmente encontrar um componente dele.Como alternativa, envie um EventQueue com um método dispatchEvent substituído.

Outras dicas

Se bem entendi, a idéia é obter um objeto "singleton" diferente para cada objeto chamador ou "contexto".Uma coisa que você pode fazer é criar uma variável global local de thread onde você escreve o ID do contexto atual.(Isso pode ser feito com AOP.) Em seguida, no getter singleton, o ID de contexto é obtido do thread local para usar como uma chave para a instância "singleton" correta para o contexto de chamada.

Em relação ao AOP, não deve haver problemas em usá-lo em miniaplicativos, pois, dependendo dos seus pontos de corte, os conselhos são tecidos em tempo de compilação e um JAR é adicionado às dependências de tempo de execução.Conseqüentemente, nenhuma evidência especial de AOP deve permanecer em tempo de execução.

@Hugo em relação ao threadlocal:

Pensei nessa solução.No entanto, a partir de experimentos, encontrei dois problemas com essa abordagem:

  1. Threads compartilhados (conexões de servidor, etc.) são problemáticos.Isso pode ser resolvido prestando atenção especial a esses threads (eles estão todos sob meu controle e estão praticamente isolados do código legado).
  2. O thread EDT é compartilhado por todos os miniaplicativos.Não consegui encontrar uma maneira de forçar a criação de um novo thread EDT para cada miniaplicativo.Isso significa que o threadlocal para o EDT seria compartilhado entre os miniaplicativos.Esse eu não tenho ideia de como resolver.Sugestões?
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top