Какая аббревиатура у механизма инверсии контроля в Spring
Что проверяют
Вопрос с подвохом на терминологию: аббревиатура самого принципа это IoC, а DI это способ его реализации. Интервьюер хочет услышать, что вы различаете эти понятия и знаете, кто в Spring управляет объектами. Следом почти всегда спрашивают, чем BeanFactory отличается от ApplicationContext и какой способ внедрения лучше.
Как отвечать
Коротко: IoC, Inversion of Control, инверсия управления. Объекты не создают свои зависимости сами, их создаёт и связывает контейнер. В Spring его так и называют, IoC-контейнер, а принцип реализуется через DI, Dependency Injection.
Дальше покажите, что понимаете механику:
- контейнер:
BeanFactoryдаёт базовое создание бинов,ApplicationContextдобавляет события, профили, сообщения для локализации, автоматическую регистрациюBeanPostProcessor, и в приложениях используется именно он; - конфигурация: аннотации
@Component,@Service,@Repositoryсо сканированием пакетов, классы@Configurationс методами@Bean, XML в старых проектах; - способы внедрения: через конструктор (рекомендуемый: поля можно сделать
final, а единственный конструктор не требует@Autowired), через сеттер для необязательных зависимостей, через поле; - область видимости: по умолчанию
singleton, один экземпляр на контекст, создаётся при старте; естьprototype, а в веб-приложенияхrequestиsession.
Хорошо добавить, что DI не единственная форма IoC. Тот же принцип «не вы вызываете, вас вызывают» работает в шаблонном методе, обработчиках событий и Service Locator.
Где спотыкаются
Отвечают «DI» и считают IoC и DI синонимами. Инверсия управления шире: DI это частный случай, в котором контейнер передаёт объекту готовые зависимости.
Везде ставят @Autowired на поля. Такой класс не создать в юнит-тесте без Spring или рефлексии, а зависимости не видны в сигнатуре. Внедрение через конструктор решает обе проблемы.
Не знают про циклические зависимости. Начиная со Spring Boot 2.6 они по умолчанию запрещены, и приложение не стартует. Правильный ответ: разорвать цикл в дизайне, а не включать spring.main.allow-circular-references.