Получить доступ

Разработчик добавил в @RestController поле private User currentUser и заполняет его в начале каждого метода. Что не так?

MiddleСервлеты и фильтрыSpring
Ещё спрашивают так:
  • Можно ли хранить данные запроса в поле контроллера?
Коротко

Контроллер — singleton, запросы обслуживаются параллельно в разных потоках. Поле currentUser общее: один пользователь увидит данные другого — гонка и утечка.

  • Данные запроса — в локальных переменных и параметрах метода
  • Текущий пользователь — @AuthenticationPrincipal или SecurityContextHolder
  • Request scope — если очень нужно состояние на запрос

А ещё Ошибка не ловится тестами в одном потоке — проявляется под нагрузкой

Так подсказку видит пользователь sotto на живом собеседовании — за пару секунд, пока вы думаете вслух.

Подробно

Каждый запрос обрабатывается своим потоком, но экземпляр контроллера один на всех, поэтому запись в поле из одного запроса видна другому — получается гонка, которая на нагрузке проявляется как чужие данные в ответе. Такие баги крайне неприятны: на разработке с одним пользователем всё работает. Правильные способы передать данные запроса — параметры метода, ThreadLocal-подобные механизмы вроде SecurityContextHolder, либо бин со scope request. Общее правило: бины Spring по умолчанию синглтоны, и изменяемое состояние в их полях недопустимо, если оно относится к конкретному запросу.

Что хотят услышать

  • Singleton и параллельные запросы.
  • Почему это гонка и утечка.
  • Правильные способы.

Частые ошибки

  • Хранить в поле сервиса или контроллера что-либо, относящееся к текущему запросу.
  • Считать проблему теоретической — она не воспроизводится при одном пользователе.

Проверьте себя

Один верный вариант. Подумайте, потом откройте ответ.

Показать варианты и ответ
  • ✓Контроллер — singleton, обслуживающий запросы разных пользователей параллельно: поле станет общим состоянием и данные перемешаются
  • ✗Ничего: Spring создаёт новый экземпляр контроллера на каждый запрос
  • ✗Поле нужно пометить @Autowired
  • ✗Проблема появится только при включённом WebFlux

Что спросят дальше

  • Как устроен SecurityContextHolder и почему он работает?
  • Чем request-scope бин отличается от параметра метода?

Разбор темы

Связанные вопросы

Закрытая бета

Подсказки на собеседовании — в реальном времени

sotto слышит вопрос интервьюера и показывает короткий ответ и план, как в блоке «Коротко». Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем