2011-08-22 32 views
1

A(簡體)版本,我面對的是如下的問題,在Spring MVC應用程序會話bean:Spring MVC的:從兩個不同的會話

兩名球員可以在一場比賽中競爭。該遊戲包括從相同的數據(例如某個國際象棋位置)開始,單獨地玩遊戲(但是同時!),然後比較結果。爲了管理這個,我有:

  • 一個處理遊戲的對象(例如,檢查玩家是否準備好,產生開始數據,檢查遊戲是否完成,...)。我們稱之爲'GameHandler',以便於參考。
  • 對於每個玩家,處理遊戲動作的對象(例如移動棋盤上的棋子)。這是一個會話範圍的bean,因爲它包含特定於玩家的狀態信息。稱此爲 'PlayerHandler':

    <豆ID = 「playerHandler」 級= 「snip.PlayerHandler」 範圍= 「會話」 > < AOP:作用域代理/ > < /豆>

問題是GameHandler需要對這兩個PlayerHandlers進行回收。但是,由於這是一個代理會話範圍bean,這些引用指向同一個bean,具體取決於我使用哪個會話訪問它。例如。兩名球員,「湯姆」和「傑裏」:

會議湯姆:既playerHandler.getGameHandler().getPlayer1().getName()playerHandler.getGameHandler().getPlayer2().getName()是湯姆 會議傑裏:都是傑裏。

現在,據我瞭解,這是預期的行爲。我的問題是而不是「這是爲什麼」,這是「我該如何解決這個問題」。我發現自己是一個解決辦法是指實際豆,而不是代理,設置在GameHandler引用時:

public void setPlayerOne(PlayerHandler playerHandler) { 
try { 
     while (playerHandler instanceof Advised) 
      playerHandler = (PlayerHandler) ((Advised) playerHandler).getTargetSource().getTarget(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
} 
... 

但是,我絕不相信這是最好的解決方案。所以我在尋找一些答案:我的設計是否是錯的 - 如果是這樣,你會如何設計?我錯過了一個簡單的解決方案嗎?這是春季限制嗎?

+0

是否只有一個遊戲正在進行或者您是否可以有多對玩家玩不同的遊戲? –

+0

@ bkent314多對必須是可能的。 – Jens

回答

1

再回到你的基本的設計,你將不得不重新考慮,如果你的「PlayerHandler」真的是會話範圍,概念上。由於您需要在給定會話(處理特定會話請求的線程)範圍之外訪問它,因此看起來不是這樣。

重構此方法的一種方法是將「PlayerHandler」移出到應用程序範圍。例如,創建一個全局單例bean,可能會將其稱爲「PlayerHandlerHolder」,其中包含將SessionHandler實例鍵入會話標識的映射。爲了防止無限填充此映射,您可以實現會話偵聽器,該會話偵聽器在會話銷燬時從地圖中刪除PlayerHandler實例。

0

解決你的問題的一種方法是create a custom scope,稱之爲「遊戲」。現在定義你的bean是這樣的:

<bean id="playerHandler" class="snip.PlayerHandler" scope="game"> 
<aop:scoped-proxy /></bean> 
+0

但是,如何區分這兩種豆呢?當我的自定義作用域('GameScope')的實現Scope的類上調用'public Object get(String name,ObjectFactory objectFactory)'方法時,我無法區分這兩個實例 - 'name'是相同的對於這兩個bean,「scopedTarget.playerHandler」。 – Jens

+0

@Jens我不是說這是你需要改變的設計的唯一部分。也許範圍代理方法根本不起作用。但是由於您顯然需要請求,會話和應用程序之間的範圍,我只是提供一個想法。 –