Хранение bean-компонентов области сеанса в @controller

Я пытаюсь сохранить свои пользовательские компоненты с областью действия сеанса в контроллере с областью действия singleton на протяжении всего их жизненного цикла в сеансе. Поэтому всякий раз, когда пользователь подключается, я хочу сохранить его в массиве с остальными пользователями, которые сохраняют свои сеансы.

Я знаю о внедрении bean-компонента с областью сеанса в @Controller через прокси-компоненты, поэтому я определил свои пользовательские компоненты с областью сеанса следующим образом:

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

Я использовал аннотацию @Autowire, чтобы внедрить этот компонент в мой класс контроллера, как показано ниже:

@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);
        //...
    }

Итак, все работает, когда первый пользователь подключается, я сохраняю его ссылку на карту. Предположим, что первая ссылка пользователя

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

Затем предположим, что подключается второй пользователь, чья ссылка:

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

Из ссылок я вижу, что мои bean-компоненты с областью сеанса работают нормально, поскольку их ссылка отличается. Однако проблемы начинаются, когда выполнение переходит в метод addUser. Еще до добавления второго пользователя на карту, я проверяю свою карту пользователей и вижу, что объект пользователя, который он хранит, заменен вторым, который называется MyUser@28zbdh. Итак, в начале конец, после добавления второго пользователя, Моя пользовательская карта выглядит так,

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

Так что ссылки обновляются всегда с последней. Я знаю, что они являются прокси-объектом для реальных объектов, но как я могу их сохранить?

Спасибо

[EDIT] Я хотел предоставить дополнительную информацию.

Я вызываю addUser из другого одноэлементного компонента как userInDBMemory.addUser(sessionUser); userInDBMemory — это еще один одноэлементный компонент, в котором я фактически добавляю своего пользователя сеанса в ConcurrentHashMap. Я хочу сохранить своих текущих онлайн-пользователей на карте, так как я хотел бы искать и запрашивать их, не обращаясь к базе данных. Поэтому я хотел бы сохранить онлайн-пользователей (у которых есть сеанс в контексте) в памяти для более легкого и быстрого доступа. Чтобы обработать срок действия сеанса, каждый онлайн-пользователь отправляет пульсацию на сервер, чтобы показать, что он в сети, у меня есть запланированный поток на сервере, работающий каждые X минут, и если он находит любого пользователя, который некоторое время не получал сердцебиение от пользователя, то он удаляет его с карты, поскольку это означает, что пользователь вышел из сети. Подводя итог моему делу, у меня есть основной контроллер, на который я получаю запросы, тогда цепочка выглядит следующим образом: @Controller-> singleton application bean-> Singleton inMemoryDB bean (где я определяю свою карту и добавляю пользователя). Autowired в @Controller, и я передаю его другим одноэлементным компонентам в качестве параметра. Спасибо за ответ.


person levye    schedule 21.12.2017    source источник
comment
Как вы вызываете addUser()? Зачем вам нужно хранить сеансовые компоненты на карте? Что происходит с сохраненным пользователем, когда, например. сессия просрочена?   -  person StanislavL    schedule 21.12.2017
comment
Привет, я обновил свой исходный пост ответами на ваш вопрос, см. часть EDIT исходного поста. Спасибо за ответ.   -  person levye    schedule 21.12.2017


Ответы (1)


Я решил свою проблему, не сохраняя компоненты сеанса напрямую, а копируя их объекты.

//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);
person levye    schedule 25.12.2017