Почему Spring не любит циклические зависимости?



Представим вполне реалистичную ситуацию:

@Service
public class OrderService {

private final PaymentService paymentService;

public OrderService(PaymentService paymentService) {
this.paymentService = paymentService;
}
}

И:

@Service
public class PaymentService {

private final OrderService orderService;

public PaymentService(OrderService orderService) {
this.orderService = orderService;
}

}
Получается:
OrderService
↓
PaymentService
↓
OrderService
↓
PaymentService
↓
...

Spring начинает создавать OrderService.
Для него нужен PaymentService.
Начинает создавать PaymentService.
Для него нужен OrderService.
А OrderService ещё не создан.

💥 Получаем циклическую зависимость.

И здесь есть важный момент. Почему constructor injection — это хорошо?
Потому что такая проблема становится очевидной сразу.
Объект невозможно создать, пока не готовы все его обязательные зависимости.
При field injection ситуация исторически могла выглядеть менее очевидно: Spring сначала создавал объект, а зависимости внедрял позже.

Но главное даже не ошибка Spring.
Циклическая зависимость часто говорит о проблеме в дизайне.

Если:
OrderService → PaymentService
PaymentService → OrderService
то возникает вопрос:

А почему эти два сервиса вообще знают друг о друге

?
Возможно, ответственность стоит разделить:

OrderService
↓
PaymentService
↓
PaymentRepository
или вынести общую бизнес-логику в отдельный компонент:

OrderService
↓
PaymentService
↓
PaymentProcessor
↑
OrderService

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

Поэтому если спрашивают:

Как исправить циклическую зависимость?

Не спешите отвечать: Поставить @Lazy.
Это может убрать проблему создания Bean, но не исправляет архитектурную связь.

Сначала стоит спросить:
«Почему вообще A должен зависеть от B, а B от A?»


Иногда лучший способ исправить циклическую зависимость — не искать правильную аннотацию, а изменить дизайн.
Просмотры: 56
Открыть в MAX Сообщить о неточности

Репосты публикации

Публикация канала

Сообщить о неточности

Опишите, что нужно исправить. Если есть источник, добавьте ссылку.

Вы покидаете datool.ru

Ссылка ведёт на внешний сайт. datool.ru не отвечает за его содержимое — проверьте адрес, прежде чем вводить пароли или платёжные данные.

Переход через 10 с

Перейти