Понимание порядка инициализации контекста Spring - PullRequest
5 голосов
/ 12 апреля 2011

У меня сложный набор компонентов и зависимостей между ними.Все бобы @Service, @Repository или @Controller аннотированы, и я использую аннотацию @PostConstruct.Есть некоторые циклические зависимости, но все равно система была правильно инициализирована Spring.

Затем я добавил простой контроллер с зависимостью только от одного из сервисов.Теоретически, система должна быть способна загружаться, потому что теоретически она может сначала настроить систему как прежде, а затем новый контроллер.Но Spring жалуется, что не может настроить контекст:

Error creating bean with name 'userService': Requested bean is currently in creation: Is there an unresolvable circular reference?

Могу ли я каким-то образом помочь Spring в том, как упорядочить контекстную инициализацию?Я думаю, что основной проблемой является userService, который часто используется в системе для аутентификации.

1 Ответ

8 голосов
/ 12 апреля 2011

Лучшим решением было бы просто убрать круговую зависимость;Я еще не встречал сценарий, где такая структура была оправдана.Но если вы хотите придерживаться этого, то, возможно, ваша вышеупомянутая проблема связана с тем, что у вас где-то есть инжектор конструктора:

Круговые зависимости Если вы используете преимущественно конструкторское внедрение, то можно написать инастройте ваши классы и компоненты так, чтобы создавался неразрешимый сценарий циклической зависимости.Рассмотрим сценарий, в котором у вас есть класс A, для которого требуется, чтобы экземпляр класса B был предоставлен посредством внедрения конструктора, и класс B, который требует, чтобы экземпляр класса A был предоставлен посредством внедрения конструктора.Если вы настраиваете bean-компоненты для классов A и B, которые будут внедряться друг в друга, контейнер Spring IoC обнаружит эту циклическую ссылку во время выполнения и сгенерирует исключение BeanCurrentlyInCreationException.

Одним из возможных решений этой проблемы является редактирование исходного кода.код некоторых ваших классов для настройки через сеттеры, а не через конструкторы.Другое решение не состоит в том, чтобы использовать инжектор конструктора и придерживаться только инжектора сеттера.Другими словами, , хотя его, как правило, следует избегать во всех случаях, кроме самых редких обстоятельств , можно настроить циклические зависимости с помощью внедрения сеттера.В отличие от типичного случая (без циклических зависимостей), циклическая зависимость между bean-компонентом A и bean-компонентом B заставит один из bean-компонентов быть введен в другой до полной инициализации (классический сценарий «курица / яйцо»).

...