Я никак не могу понять, нормально ли хранить общие для всех пользователей объекты в статических переменных класса-контроллера Spring?
Например нужно реализовать чат на 5 последних сообщений без базы и файлов. Если создать ArrayList и метод добавления в него сообщения, то вроде все работает.
Но такой подход нормальный? Это не вызовет коллизий связанных с многопоточностью, как если бы это было не в Spring?
Или может быть есть другие способы хранить уже сконструированные объекты для общего пользования? Задача состоит в том, что бы хранить именно экземпляры классов, которые долго создаются, но нужны при каждом заходе пользователя.
Нет, не нормально (да и вообще в Spring'e хранить что-то статично — верх безумия — с его-то Dependency Injection).
То что вы делаете называется кешированием данных. Оно бывает разное в зависимости от целей, в вашем случае оно на уровне приложения (т.е. один инстанс кеша на всё приложение). На сколько я помню в Spring'e есть механизм объявления бина (bean), при этом есть возможность задать его область видимости (scope). Так вот ваш случай — singleton или (если есть конечно) application bean.
По поводу многопоточности — естественная проблема общих ресурсов. Тут, к сожалению, и Spring вам не поможет — нужно реализовывать самому используя конструкцию synchronized.
Это плохо. Если у вас есть два инстанса application context (например 2 веб аппликации на одном сервере, или во время юнит тестов) — этот кэш будет общим.
Сделайте еще один бин синглетон, в котором будут храниться эти данные