如何在不传递 ID 的情况下识别在哪个 Java Applet 上下文中运行?

发布于 2024-07-04 03:20:50 字数 300 浏览 7 评论 0原文

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

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

I'm part of a team that develops a pretty big Swing Java Applet. Most of our code are legacy and there are tons of singleton references. We've bunched all of them to a single "Application Context" singleton. What we now need is to create some way to separate the shared context (shared across all applets currently showing) and non-shared context (specific to each applet currently showing).

However, we don't have an ID at each of the locations that call to the singleton, nor do we want to propagate the ID to all locations. What's the easiest way to identify in which applet context we're running? (I've tried messing with classloaders, thread groups, thread ids... so far I could find nothing that will enable me to ID the origin of the call).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

无声无音无过去 2024-07-11 03:20:50

单身人士是邪恶的,你还指望什么? ;)

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

其他技巧:

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

如果您位于每个小程序实例线程中,那么您可以设置一个 ThreadLocal。

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

Singletons are evil, what do you expect? ;)

Perhaps the most comprehensive approach would be to load the bulk of the applet in a different class loader (use java.net.URLClassLoader.newInstance). Then use a WeakHashMap to associate class loader with an applet. If you could split most of the code into a common class loader (as a parent of each per-applet class loader) and into the normal applet codebase, that would be faster but more work.

Other hacks:

If you have access to any component, you can use Component.getParent repeatedly or SwingUtilities.getRoot.

If you are in a per-applet instance thread, then you can set up a ThreadLocal.

From the EDT, you can read the current event from the queue (java.awt.EventQueue.getCurrentEvent()), and possibly find a component from that. Alternatively push an EventQueue with a overridden dispatchEvent method.

○闲身 2024-07-11 03:20:50

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

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

If I understand you correctly, the idea is to get a different "singleton" object for each caller object or "context".
One thing you can do is to create a thread-local global variable where you write the ID of the current context. (This can be done with AOP.) Then in the singleton getter, the context ID is fetched from the thread-local to use as a key to the correct "singleton" instance for the calling context.

Regarding AOP there should be no problem using it in applets since, depending on your point-cuts, the advices are woven at compile time and a JAR is added to the runtime dependencies. Hence, no special evidence of AOP should remain at run time.

彩扇题诗 2024-07-11 03:20:50

@Hugo 关于 threadlocal:

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

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

@Hugo regarding threadlocal:

I thought about that solution. However, from experiments I found two problems with that approach:

  1. Shared thread (server connections, etc) are problematic. This can be solved though by paying special attention to these thread (they're all under my control and are pretty much isolated from the legacy code).
  2. The EDT thread is shared across all applets. I failed to find a way to force the creation of a new EDT thread for each applet. This means that the threadlocal for the EDT would be shared across the applets. This one I have no idea how to solve. Suggestions?
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文