如何在不传递 ID 的情况下识别在哪个 Java Applet 上下文中运行?
我所在的团队开发了一个相当大的 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
单身人士是邪恶的,你还指望什么? ;)
也许最全面的方法是在不同的类加载器中加载大部分 applet(使用 java.net.URLClassLoader.newInstance)。 然后使用 WeakHashMap 将类加载器与小程序关联起来。 如果您可以将大部分代码拆分到一个公共类加载器(作为每个小程序类加载器的父级)和普通小程序代码库中,那么速度会更快,但工作量也会更大。
其他技巧:
如果您有权访问任何组件,则可以重复使用 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.
如果我理解正确的话,这个想法是为每个调用者对象或“上下文”获取不同的“单例”对象。
您可以做的一件事是创建一个线程局部全局变量,在其中写入当前上下文的 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.
@Hugo 关于 threadlocal:
我考虑过这个解决方案。 然而,从实验中我发现这种方法有两个问题:
@Hugo regarding threadlocal:
I thought about that solution. However, from experiments I found two problems with that approach: