Ответ
Циклические зависимости (A → B → A) — это антипаттерн, сигнализирующий о проблемах проектирования. Временные решения в Spring:
1. Использование @Lazy
Инжектируйте одну из зависимостей лениво, разрывая цикл на этапе инициализации.
@Service
public class ServiceA {
private final ServiceB serviceB;
public ServiceA(@Lazy ServiceB serviceB) { // Lazy-прокси для B
this.serviceB = serviceB;
}
}
@Service
public class ServiceB {
private final ServiceA serviceA; // Внедряется реальный бин A
public ServiceB(ServiceA serviceA) {
this.serviceA = serviceA;
}
}
2. Инжекция через сеттер или поле
Вместо инжекции через конструктор (которая вызывает ошибку на этапе подъёма контекста), используйте @Autowired на поле или сеттер-методе.
3. Рефакторинг архитектуры (рекомендуется)
- Вынесите общую логику в третий сервис (паттерн Mediator).
- Используйте интерфейсы и инжектируйте их, возможно, с помощью
@Lazy. - Примените принцип инверсии зависимостей (DIP) — сделайте так, чтобы оба класса зависели от абстракции, а не друг от друга.
Важно: Spring Boot ≥ 2.6 по умолчанию запрещает циклические зависимости. Для временного обхода можно установить spring.main.allow-circular-references=true, но это плохая практика. Лучшее решение — рефакторинг.