BeanFactory и ApplicationContext
BeanFactory — базовый контракт IoC-контейнера: найти bean по имени/типу, проверить scope и получить экземпляр. ApplicationContext расширяет контейнер инфраструктурой обычного приложения.
| Возможность | BeanFactory | ApplicationContext |
|---|---|---|
| создание и поиск bean | да | да |
| dependency injection | да | да |
| события приложения | нет в базовом контракте | да |
i18n через MessageSource | нет | да |
| ресурсы и pattern scan | базово/отдельно | интегрировано |
| Environment и profiles | нет в контракте | да |
| lifecycle контекста | минимальный API | refresh/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.