Что такое Dependency Injection (DI)
Что проверяют
Отличаете ли вы принцип от библиотеки. Внедрение зависимостей это про архитектуру, контейнер это инструмент, и подмена одного другим слышна сразу.
Как отвечать
Dependency Injection это когда объект не создаёт свои зависимости сам, а получает их снаружи. Обычно через конструктор:
@Service
public class OrderService {
private final PaymentGateway payments;
public OrderService(PaymentGateway payments) { this.payments = payments; }
}Что это даёт: класс зависит от абстракции, а не от конкретной реализации. В тесте вместо настоящей зависимости подставляется заглушка, в проде реализация меняется в одном месте, а по сигнатуре конструктора видно, от чего класс зависит вообще.
Способы внедрения: конструктор (по умолчанию, зависимость обязательна), свойство или сеттер (для необязательных), метод (когда нужна ровно в одном вызове).
В Spring граф собирает контейнер по типам аргументов конструктора, аннотация @Autowired на единственном конструкторе не нужна. Важны области видимости бинов: singleton по умолчанию, prototype на каждое обращение, request и session в веб-приложении.
Где спотыкаются
Считают, что DI это библиотека. Передать зависимость руками в конструктор это уже DI, контейнер лишь избавляет от сборки графа вручную.
Просят зависимость у контейнера прямо внутри метода. Это Service Locator, и по сигнатуре больше не видно, что классу нужно.
Внедряют конкретный класс вместо абстракции, после чего подменить его в тесте нечем.
Внедряют бин с областью prototype в синглтон и получают один и тот же экземпляр на всё время жизни приложения, хотя ждали новый.