856просмотров
17.4%от подписчиков
19 марта 2026 г.
📷 ФотоScore: 942
🍀 Как работает Dependency Injection под капотом в Spring Framework Dependency Injection (DI) — один из фундаментальных механизмов Spring.
Он позволяет автоматически внедрять зависимости между объектами, избавляя разработчика от ручного создания и связывания компонентов. Но что происходит внутри Spring, когда вы пишете обычный код вроде такого:
@Service
public class OrderService { private final PaymentService paymentService; public OrderService(PaymentService paymentService) { this.paymentService = paymentService; }
} На первый взгляд кажется, что Spring просто создает объекты и подставляет их в качестве зависимостей. На самом деле под капотом работает довольно сложный механизм. ➖ Сканирование компонентов При запуске приложения Spring сначала сканирует классы в указанных пакетах.
За это отвечает механизм сканирования компонентов. Так например, Spring ищет классы отмеченные аннотациями: @Component, @Service, @Repository, @Controller, @Configuration и др. Каждый найденный класс регистрируется как бин (Bean) и на этом этапе создается описание бина (Bean Definition), часто называемая метаинформацией. ➖ Регистрация BeanDefinition Spring не создает объекты сразу. Сначала будут сформированы метаданные (Bean Definition), как уже упоминалось ранее. В них хранится информация: класс бина, область видимости (scope), зависимости и настройки конфигурации. Вся эта информация поменяется в BeanFactory. ➖ Создание ApplicationContext Затем Spring создаёт ApplicationContext — контейнер, который управляет всеми бинами.
В сущности, он отвечает за создание объектов, управление их жизненным циклом, внедрение зависимостей и их конфигурацию. По сути это и есть знаменитый Spring IoC Container — частная реализация принципа Inversion of Control (IoC). ➖ Создание бинов Когда контейнер инициализируется, Spring начинает создавать объекты. Для этого Spring строит граф зависимостей и создает объекты в правильном порядке. Упрощенно алгоритм можно описать следующим образом: найти BeanDefinition, создать объект через конструктор, определить зависимости, найти нужные бины, внедрить зависимости. Например, в таком порядке: OrderService → PaymentService → PaymentRepository. ➖ Внедрение зависимостей Внедрение может происходить несколькими способами: через конструктор (Constructor Injection), через поле (Field Injection), через сеттер (Setter Injection). Самый рекомендуемый способ считается внедрение зависимостей через конструкторов. Просто потому, что это наиболее естественный для Java способ, как представителя ООП. Также, такой подход наиболее гибкий, позволяет поддерживать код расширяемым, а тестирование простым.
public OrderService(@Autowired PaymentService paymentService) ➖ Постобработка бинов (Bean Post Processing) После создания объекта Spring может его модифицировать. За это отвечает BeanPostProcessor. Именно в этот момент здесь создаются знаменитые прокси-объекты, методы заворачиваются в транзакции (аннотация @Transactional), организовывается безопасность (аннотация @Secured) и применяется AOP. 📌 Заключение После всех этапов бин считается собранным и готовым к использованию. При попытки внедрения бина Spring просто берет готовый объект из контейнера и подставляет его в нужно месте внедрения. Как можно судить, Dependency Injection в Spring — это не просто «магия». Под капотом происходит несколько этапов, благодаря которым Spring может управлять сложными приложениями, состоящим из сотни компонентов. ⬇️ А как ты рассказываешь на собеседовании о Spring Dependency Injection? Пиши о своем опыте в комментариях.
👍 Понравился этот пост? Подписывайся, ставь лайк и поделись постом с другом или коллегой.