2008-08-10 16 views
6

我是一个团队的一员,开发了一个非常大的Swing Java Applet。我们的大部分代码都是遗留的,并且有大量的单例引用。我们已经将它们全部集中到单个“应用程序上下文”单例中。我们现在需要的是创建一种方法来分离共享上下文(在当前显示的所有小程序中共享)和非共享上下文(特定于当前显示的每个小程序)。如何识别运行哪个Java Applet上下文而不传递ID?

但是,我们在每个调用单例的位置都没有ID,我们也不想将ID传播到所有位置。识别我们正在运行的applet环境的最简单方法是什么? (我已经尝试了加载类加载器,线程组,线程ID ...到目前为止,我找不到任何能够使我识别调用的起源的东西)。

回答

2

单身是邪恶的,你期望什么? ;)

也许最全面的方法是在不同的类加载器中加载大部分applet(使用java.net.URLClassLoader.newInstance)。然后使用WeakHashMap将类加载器与applet关联。如果你可以将大部分代码拆分成一个通用的类加载器(作为每个applet类加载器的父代)和正常的applet代码库,那将会更快,但是更多的工作。

其他黑客:

如果你有机会获得任何组件,您可以使用Component.getParent反复或SwingUtilities.getRoot。

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

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

+0

这是(目前为止)我在这个主题上看到的最好的想法集合。我特别喜欢“推送自定义事件队列” - 我会尝试一下。 – 2008-09-17 04:56:28

0

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

关于AOP,在小应用程序中使用它应该没有问题,因为根据您的切入点,建议在编译时编织,JAR被添加到运行时依赖项中。因此,运行时不应存在AOP的特殊证据。

0

关于ThreadLocal的@Hugo:

我想过这个问题的解决方案。然而,从实验中我发现这种方法有两个问题:

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

您应该可以通过为归档变量使用不同的值来获得新的EDT线程。我认为你可以添加一个随机jar名称到最后,即使它存在。 – 2008-10-11 01:10:16