简体   繁体   English

在@controller中存储会话范围bean

[英]Storing session-scope beans in @controller

I am trying to store my session-scoped user beans in a singleton-scoped controller throughout their lifecycle in session. 我试图将会话范围内的用户bean在会话的整个生命周期中存储在一个单一范围内的控制器中。 So whenever a user is being connected, I want to store it in an array with the rest of the users those who keep their sessions. 因此,无论何时连接用户,我都希望将其与其他保持会话的用户存储在一个数组中。

I know about injecting a session-scoped bean into a @Controller through proxy beans so that i have defined my session-scoped user beans as follow, 我知道通过代理bean将会话范围的bean注入到@Controller中,这样我就定义了如下会话范围的用户bean,

@Bean
@Scope(value="session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public IUser user ()
{
    IUser user = new MyUser();
    return user;
}

I have used @Autowire annotation to inject that bean into my controller class as below, 我已经使用@Autowire注解将该bean注入到我的控制器类中,如下所示,

@Autowired
private IUser sessionUser;

So whenever a user is getting connected, I am storing that user in a ConcurrentHashMap which is defined and added as below, 因此,只要有用户建立连接,我就会将该用户存储在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);
        //...
    }

So everything is working when the first user gets connected, I store its reference to map. 因此,当第一个用户建立连接时,一切正常,我将其引用存储到map。 Let's assume first user reference is 假设第一个用户参考是

us.com.soemthing.orm.model.MyUser@135debf

Then let us assume the second user gets connected whose reference is, 然后,让我们假设第二个用户已连接,其引用为:

us.com.soemthing.orm.model.MyUser@28zbdh

From the references, I can see that my session-scoped beans work fine as their reference is different. 从参考中,我可以看到我的会话作用域Bean可以正常工作,因为它们的参考不同。 However , problems start when execution goes into addUser method. 但是 ,当执行进入addUser方法时,问题就开始了。 Even before adding the second user to the map, I check my userMap and see that user object it is storing replaced with the second one which is MyUser@28zbdh. 甚至在将第二个用户添加到地图之前,我都要检查我的userMap并看到它存储的用户对象已替换为第二个用户,即MyUser @ 28zbdh。 So at the end, after adding the second user, My user map looks like this, 因此,最后,在添加第二个用户之后,我的用户地图如下所示,

Map --> "1"- us.com.soemthing.orm.model.MyUser@28zbdh
Map --> "2"- us.com.soemthing.orm.model.MyUser@28zbdh

So that references are being updated always with the last one. 这样,引用始终会随着最后一个引用而更新。 I know that they are the proxy object to real objects but how I can store them? 我知道它们是真实对象的代理对象,但是如何存储它们呢?

Thanks 谢谢

[EDIT] I wanted to provide additional information. [编辑]我想提供其他信息。

I am calling addUser from another singleton bean as, userInDBMemory.addUser(sessionUser); 我正在从另一个单例bean中调用addUser,如userInDBMemory.addUser(sessionUser);。 userInDBMemory is another singleton bean where i add my session user to a ConcurrentHashMap actually. userInDBMemory是另一个单例bean,我实际上将会话用户添加到ConcurrentHashMap中。 I want to store my current online users on a map as I would like to search and query them without going to the database. 我想将当前的在线用户存储在地图上,因为我想搜索和查询他们而无需访问数据库。 So i would like to keep online users (who has a session in context) in memory for easier and faster access. 因此,我想将在线用户(在上下文中具有会话的用户)保留在内存中,以便更轻松,更快速地访问。 To handle session expires, every online user sends a heartbeat to server to show he is online, I have a scheduled thread on server running in every X minutes and if it finds any user who didn't get heartbeat from the user for a while then it removes it from the map as it means user went offline. 为了处理会话过期,每个在线用户都会向服务器发送心跳信号以表明他已经在线,我在服务器上每隔X分钟运行一个调度线程,如果它发现有一段时间没有从用户那里获得心跳信号的用户,那么它将其从地图中删除,因为这意味着用户已离线。 To summary my case I have a main controller where i get requests then the chain is like this: @Controller->singleton application bean->Singleton inMemoryDB bean (where I define my map and add user) My SessionUser session-scoped bean is @Autowired in @Controller and i pass it to other singleton beans as a parameter.Thanks for the response. 总结一下我的情况,我有一个主控制器来接收请求,然后链是这样的:@ Controller-> singleton应用程序bean-> Singleton inMemoryDB bean(在其中定义我的地图并添加用户)我的SessionUser会话作用域bean是@在@Controller中自动连线,我将其作为参数传递给其他单例bean。感谢响应。

I have solved my problem by not storing session-scoped beans directly but their object copies. 通过不直接存储会话范围的bean而是存储它们的对象副本,我已经解决了我的问题。

//IMyUser sessionUser; --let say sessionUser is session-scoped bean in a singleton bean

so instead of ; 所以代替;

userInDBMemory.addUser(sessionUser);

I have copied the user first and added that object instead. 我先复制了用户,然后添加了该对象。

 IMyUser copyUser = new MyUser();
 BeanUtils.copyProperties(sessionUser, copyUser);
 userInDBMemory.addUser(copyUser);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM