Получить доступ

ApplicationContext и конфигурация

BeanFactory против ApplicationContext, способы конфигурации, @Configuration full/lite, профили и Environment, @Conditional.

BeanFactory против ApplicationContext

BeanFactory — базовый контейнер с ленивым созданием бинов по запросу. ApplicationContext — его надстройка, которую и используют на практике: он жадно создаёт синглтоны на старте (ошибки конфигурации видны сразу — fail-fast), публикует события (ApplicationEvent), поддерживает i18n, автоматически находит BeanPostProcessor/BeanFactoryPostProcessor и интегрируется с AOP.

Практически всегда работают с ApplicationContext; BeanFactory — это его «ядро» для понимания.

Способы конфигурации

Бины объявляют тремя путями: Java-config (@Configuration + методы @Bean), аннотации + component-scan (@Component на классе) и XML (легаси). Современный стандарт — Java-config плюс сканирование компонентов; XML встречается в старых проектах.

Свой класс помечают @Component/@Bean-стереотипом, чужой/библиотечный регистрируют через @Bean-метод (подробнее — в уроке про стереотипы).

@Configuration: full против lite

Класс с @Configuration Spring проксирует через CGLIB (full mode). Зачем: если один @Bean-метод вызывает другой @Bean-метод, прокси перехватывает вызов и возвращает тот же singleton из контейнера, а не создаёт новый объект.

Если же поставить @Bean в обычном классе без @Configuration (lite mode), такого проксирования нет — прямой вызов @Bean-метода создаст НОВЫЙ объект мимо контейнера. Это классический источник тонких багов с «двумя экземплярами синглтона».

@Configuration
class AppConfig {
    @Bean DataSource ds() { return new HikariDataSource(); }
    @Bean OrderRepo repo() { return new OrderRepo(ds()); } // ds() вернёт тот же singleton (full mode)
}

Профили и Environment

@Profile("dev") делает бин/конфигурацию активными только в указанном профиле (spring.profiles.active=dev) — так разводят dev/test/prod-инфраструктуру. Environment абстрагирует источники свойств (переменные окружения, application.yml, аргументы запуска) с приоритетами.

Свойства внедряют через @Value("${...}") (точечно) или, что предпочтительнее, через типобезопасные @ConfigurationProperties-классы (группа свойств с валидацией).

@Conditional и BeanFactoryPostProcessor

@Conditional регистрирует бин только при выполнении условия. На его основе построены @ConditionalOnProperty/OnMissingBean/OnClass — фундамент Boot-автоконфигурации (отдельный урок): «создайте бин, только если его ещё нет / есть нужный класс / включено свойство».

BeanFactoryPostProcessor (BFPP), в отличие от BeanPostProcessor, работает раньше — над BeanDefinition'ами до создания бинов (пример — подстановка плейсхолдеров свойств). Порядок «BFPP правит определения → бины создаются → BPP правят объекты» полезно держать в голове.

Как отвечать на собеседовании

Противопоставьте BeanFactory (ленивый) и ApplicationContext (жадные синглтоны/события/fail-fast). Объясните full vs lite @Configuration (CGLIB-прокси → межбиновые вызовы дают тот же singleton; в lite — новый объект). Назовите профили и @ConfigurationProperties, и различите BFPP (над определениями) и BPP (над объектами), с @Conditional как мостом к автоконфигурации.

Вопросы по теме

Читайте также

Закрытая бета

Знать тему — половина дела

На живом собеседовании sotto слышит вопрос интервьюера и показывает короткий ответ и план. Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем