BeanFactory и ApplicationContext

BeanFactory — базовый контракт IoC-контейнера: найти bean по имени/типу, проверить scope и получить экземпляр. ApplicationContext расширяет контейнер инфраструктурой обычного приложения.

ВозможностьBeanFactoryApplicationContext
создание и поиск beanдада
dependency injectionдада
события приложениянет в базовом контрактеда
i18n через MessageSourceнетда
ресурсы и pattern scanбазово/отдельноинтегрировано
Environment и profilesнет в контрактеда
lifecycle контекстаминимальный APIrefresh/start/close через реализации
try (var context =
             new AnnotationConfigApplicationContext(AppConfig.class)) {
    PaymentService service = context.getBean(PaymentService.class);
    service.run();
}

В прикладном Spring-коде почти всегда используют ApplicationContext или дают framework управлять им. Низкоуровневый BeanFactory полезен авторам инфраструктуры и контейнерных расширений.

Важное исправление

Фраза «BeanFactory всегда lazy, ApplicationContext всегда eager» неверна. Lazy/eager зависит от scope, @Lazy, definition и фазы refresh. Типичная реализация контекста при refresh заранее создаёт non-lazy singleton beans, но сам механизм BeanFactory тоже умеет pre-instantiation.

Аннотации обрабатываются не магией интерфейса ApplicationContext, а зарегистрированными BeanPostProcessor и другими extension points. Если вручную создать голый DefaultListableBeanFactory, нужные processors придётся регистрировать самому.

Ошибки

  • вызывать getBean по всему доменному коду вместо DI;
  • создавать второй контекст ради получения одного bean;
  • считать ApplicationContext самим бизнес-реестром;
  • забыть закрыть самостоятельно созданный context.

На собеседовании

Расширяет ли ApplicationContext возможности BeanFactory? Да, включая события, сообщения, resources и environment.

Всегда ли контекст создаёт все бины сразу? Нет; типичные non-lazy singletons — да, но scopes и @Lazy меняют поведение.

Кто реализует @Autowired? Соответствующие post-processors контейнера.

Нужно ли внедрять ApplicationContext в каждый сервис? Нет, это service locator и скрытая зависимость.

Связано: Основные сущности Spring Framework, Жизненный цикл бина, Spring Dependency Injection и Inversion of Control.