2008-08-10 17 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