8

我是一个开发相当大的 Swing Java Applet 的团队的一员。我们的大部分代码都是遗留的,并且有大量的单例引用。我们将所有这些都捆绑到一个“应用程序上下文”单例中。我们现在需要创建某种方法来分离共享上下文(在当前显示的所有小程序之间共享)和非共享上下文(特定于当前显示的每个小程序)。

但是,我们没有在调用单例的每个位置都有一个 ID,我们也不想将 ID 传播到所有位置。识别我们在哪个小程序上下文中运行的最简单方法是什么?(我试过弄乱类加载器、线程组、线程ID......到目前为止,我找不到任何可以让我识别调用来源的东西)。

4

3 回答 3

3

单身人士是邪恶的,你期待什么?;)

也许最全面的方法是将大部分小程序加载到不同的类加载器中(使用 java.net.URLClassLoader.newInstance)。然后使用 Wea​​kHashMap 将类加载器与小程序相关联。如果您可以将大部分代码拆分为一个公共类加载器(作为每个小程序类加载器的父级)和普通小程序代码库,那会更快但工作量更大。

其他黑客:

如果您有权访问任何组件,则可以重复使用 Component.getParent 或 SwingUtilities.getRoot。

如果您在每个applet 实例线程中,那么您可以设置一个ThreadLocal。

在 EDT 中,您可以从队列 (java.awt.EventQueue.getCurrentEvent()) 中读取当前事件,并可能从中找到一个组件。或者,使用重写的 dispatchEvent 方法推送 EventQueue。

于 2008-09-05T21:13:10.303 回答
0

如果我理解正确,这个想法是为每个调用者对象或“上下文”获取不同的“单例”对象。您可以做的一件事是创建一个线程局部全局变量,您可以在其中写入当前上下文的 ID。(这可以通过 AOP 完成。)然后在单例 getter 中,从线程本地获取上下文 ID,以用作调用上下文的正确“单例”实例的键。

关于 AOP,在 applet 中使用它应该没有问题,因为根据您的切入点,建议在编译时编织,并将 JAR 添加到运行时依赖项中。因此,在运行时不应保留任何 AOP 的特殊证据。

于 2008-08-11T12:32:02.480 回答
0

@Hugo 关于线程本地:

我想到了那个解决方案。然而,从实验中我发现这种方法存在两个问题:

  1. 共享线程(服务器连接等)是有问题的。这可以通过特别注意这些线程来解决(它们都在我的控制之下,并且几乎与遗留代码隔离)。
  2. EDT 线程在所有小程序之间共享。我没有找到一种方法来强制为每个小程序创建一个新的 EDT 线程。这意味着 EDT 的 threadlocal 将在 applet 之间共享。这个我不知道如何解决。建议?
于 2008-08-11T20:06:28.070 回答