Ответ вслух Middle IoC и внедрение зависимостей обновлено

Циклические зависимости

Вопрос

Как Spring обрабатывает циклические зависимости и что вы делаете, когда сталкиваетесь с ними?

Попробуйте сами

Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.

Показать ответ и разбор

Коротко

Если два бина требуют друг друга через конструкторы, их нельзя создать, и Spring падает при старте с описанием цикла. Для внедрения через поля и сеттеры Spring умеет выдать раннюю ссылку на недостроенный бин из кеша синглтонов, но с Boot 2.6 циклы запрещены по умолчанию и это поведение надо явно включать флагом.

Что должно прозвучать в ответе

  • С конструкторами цикл невозможно разрешить, старт падает

  • С Boot 2.6 циклы запрещены по умолчанию и для полей

  • Раньше для полей и сеттеров Spring подсовывал ранние ссылки (трёхуровневый кеш синглтонов)

  • Цикл это признак плохого разделения ответственности

  • Решения: вынести общий код, события, интерфейс; @Lazy как временный обход

Что могут спросить следом

  • Почему ранняя ссылка ломается, если бин оборачивается в прокси?
  • Как найти цикл по тексту ошибки?

Разбор

Если два бина требуют друг друга через конструкторы, их нельзя создать, и Spring падает при старте с описанием цикла. Для внедрения через поля и сеттеры Spring умеет выдать раннюю ссылку на недостроенный бин из кеша синглтонов, но с Boot 2.6 циклы запрещены по умолчанию и это поведение надо явно включать флагом. Я флаг не включаю: цикл почти всегда означает, что ответственность разделена неудачно. Смотрю, какой метод одного сервиса нужен другому, и выношу его в отдельный бин, или развязываю через событие ApplicationEventPublisher, или ввожу интерфейс на стороне потребителя. @Lazy на параметре конструктора допустим как временная мера, он подставляет прокси.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.