Search
Write a publication
Pull to refresh
122.9

Аннотация Lazy как спасение от циклических зависимостей

Level of difficultyEasy
Reading time2 min
Views503

В прошлом посте команда Spring АйО подробно разобрала, как @Lazy помогает экономить ресурсы и ускорять старт приложения. Но забыли упомянуть ещё один крайне полезный кейс применения этой аннотации — борьбу с циклическими зависимостями.

Если в приложении бин A зависит от бина B, а бин B в свою очередь зависит от A — вы получите классическую circular dependency. Spring просто не сможет создать такие бины через конструкторы. Однако, если применить @Lazy на одном из аргументов, Spring обернёт зависимость в прокси и разорвёт цикл.

@Service
public class ServiceA {
    private final ServiceB serviceB;

    public ServiceA(@Lazy ServiceB serviceB) {
        this.serviceB = serviceB;
    }
}

Важно: @Lazy здесь влияет только на точку инжекции, а не на весь бин. Оба бина будут инициализированы жадно, но зависимость будет подгружена позже.

Если же вы хотите, чтобы инициализация бина проходила лениво (при первом обращении к бину), то отметьте аннотацией @Lazy и сам бин тоже:

@Lazy
@Service
public class ServiceB {
    // ...
}

⚠️ Использование свойства: spring.main.allow-circular-references=true

Это ещё один способ разрешить циклы на уровне конфигурации. Spring сам предложит это в логах, если столкнётся с циклом:

Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true.

Но будьте осторожны:

  • Это работает только с field-based и setter-based инжекцией

  • Если используете constructor-based инжекцию, то приложение по прежнему не запустится, лишь немного изменится сообщение в логах

  • До Spring Boot 2.6 это поведение было включено по умолчанию — после обновления многие столкнулись с неожиданными фейлами.

Поэтому такой подход стоит рассматривать как временную меру, а не как архитектурное решение.


Присоединяйтесь к русскоязычному сообществу разработчиков на Spring Boot в телеграм — Spring АйО, чтобы быть в курсе последних новостей из мира разработки на Spring Boot и всего, что с ним связано

Tags:
Hubs:
+3
Comments1

Articles

Information

Website
t.me
Registered
Employees
11–30 employees