Что такое бины в Spring и как их создавать
Что проверяют
Знаете ли вы, как объект попадает в контейнер и какой способ где уместен, плюс область видимости и жизненный цикл бина. Типичные уточнения: чем @Component отличается от @Bean и что произойдёт, если бин prototype внедрить в singleton.
Как отвечать
Бин это объект, созданием, связыванием и жизнью которого управляет контейнер Spring. Способы его зарегистрировать:
- сканирование:
@Componentи стереотипы@Service,@Repository(плюс трансляция исключений),@Controllerи@RestController. В Spring Boot сканирование идёт от пакета класса с@SpringBootApplicationвниз; @Beanв@Configuration: для классов, которые нельзя пометить аннотацией, напримерObjectMapperилиRestClient. В полноценном@Configurationвызов одного@Bean-метода из другого возвращает тот же синглтон через CGLIB-прокси, а приproxyBeanMethods = falseполучится новый объект;- программно:
registerBeanуGenericApplicationContext, условные бины автоконфигураций Boot с@ConditionalOnMissingBean; - XML:
<bean>, только в легаси.
Области видимости: singleton по умолчанию, один на контекст; prototype, новый при каждом запросе; веб-скоупы request, session, application. Синглтоны создаются при старте контекста, @Lazy откладывает создание до первого обращения.
Жизненный цикл: создание экземпляра, внедрение зависимостей, *Aware-колбэки, BeanPostProcessor до инициализации, @PostConstruct или afterPropertiesSet, BeanPostProcessor после (здесь появляются прокси), работа, @PreDestroy при закрытии контекста. Для prototype методы уничтожения контейнер не вызывает.
Где спотыкаются
Отождествляют singleton-бин с паттерном Singleton. Скоуп означает один экземпляр на контекст и имя бина, а не на JVM: можно объявить два бина одного класса.
Внедряют prototype в singleton и ждут новый объект на каждый вызов. Внедрение происходит один раз, при создании синглтона; нужен ObjectProvider<T> или @Lookup.
Хранят изменяемое состояние в поле синглтон-бина, например текущего пользователя. Бин общий для всех потоков запросов, и данные одного пользователя утекут к другому.