[英]Storing session-scope beans in @controller
我試圖將會話范圍內的用戶bean在會話的整個生命周期中存儲在一個單一范圍內的控制器中。 因此,無論何時連接用戶,我都希望將其與其他保持會話的用戶存儲在一個數組中。
我知道通過代理bean將會話范圍的bean注入到@Controller中,這樣我就定義了如下會話范圍的用戶bean,
@Bean
@Scope(value="session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public IUser user ()
{
IUser user = new MyUser();
return user;
}
我已經使用@Autowire注解將該bean注入到我的控制器類中,如下所示,
@Autowired
private IUser sessionUser;
因此,只要有用戶建立連接,我就會將該用戶存儲在ConcurrentHashMap中,該對象的定義和添加如下所示,
private ConcurrentHashMap<Integer,IUser> userMap = new ConcurrentHashMap<>(50,0.9f,2);
public void addUser(IUser user)
{
if(user == null) return;
IUser retUser = userMap.putIfAbsent(user.getDbid(),user);
//...
}
因此,當第一個用戶建立連接時,一切正常,我將其引用存儲到map。 假設第一個用戶參考是
us.com.soemthing.orm.model.MyUser@135debf
然后,讓我們假設第二個用戶已連接,其引用為:
us.com.soemthing.orm.model.MyUser@28zbdh
從參考中,我可以看到我的會話作用域Bean可以正常工作,因為它們的參考不同。 但是 ,當執行進入addUser方法時,問題就開始了。 甚至在將第二個用戶添加到地圖之前,我都要檢查我的userMap並看到它存儲的用戶對象已替換為第二個用戶,即MyUser @ 28zbdh。 因此,最后,在添加第二個用戶之后,我的用戶地圖如下所示,
Map --> "1"- us.com.soemthing.orm.model.MyUser@28zbdh
Map --> "2"- us.com.soemthing.orm.model.MyUser@28zbdh
這樣,引用始終會隨着最后一個引用而更新。 我知道它們是真實對象的代理對象,但是如何存儲它們呢?
謝謝
[編輯]我想提供其他信息。
我正在從另一個單例bean中調用addUser,如userInDBMemory.addUser(sessionUser);。 userInDBMemory是另一個單例bean,我實際上將會話用戶添加到ConcurrentHashMap中。 我想將當前的在線用戶存儲在地圖上,因為我想搜索和查詢他們而無需訪問數據庫。 因此,我想將在線用戶(在上下文中具有會話的用戶)保留在內存中,以便更輕松,更快速地訪問。 為了處理會話過期,每個在線用戶都會向服務器發送心跳信號以表明他已經在線,我在服務器上每隔X分鍾運行一個調度線程,如果它發現有一段時間沒有從用戶那里獲得心跳信號的用戶,那么它將其從地圖中刪除,因為這意味着用戶已離線。 總結一下我的情況,我有一個主控制器來接收請求,然后鏈是這樣的:@ Controller-> singleton應用程序bean-> Singleton inMemoryDB bean(在其中定義我的地圖並添加用戶)我的SessionUser會話作用域bean是@在@Controller中自動連線,我將其作為參數傳遞給其他單例bean。感謝響應。
通過不直接存儲會話范圍的bean而是存儲它們的對象副本,我已經解決了我的問題。
//IMyUser sessionUser; --let say sessionUser is session-scoped bean in a singleton bean
所以代替;
userInDBMemory.addUser(sessionUser);
我先復制了用戶,然后添加了該對象。
IMyUser copyUser = new MyUser();
BeanUtils.copyProperties(sessionUser, copyUser);
userInDBMemory.addUser(copyUser);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.