В чём разница между BeanFactory и ApplicationContext?
BeanFactory — базовый IoC-контейнер с ленивой инициализацией без автообнаружения постпроцессоров. ApplicationContext расширяет его: eager-инициализация singleton-бинов, события, i18n, Environment/profiles — в реальных проектах всегда используют ApplicationContext.
BeanFactory vs ApplicationContext
BeanFactory — это базовый контейнер IoC из пакета org.springframework.beans.factory. Он поддерживает только ленивую инициализацию бинов и базовый dependency injection. ApplicationContext расширяет BeanFactory и добавляет инфраструктурные возможности: публикацию событий через ApplicationEventPublisher, интернационализацию через MessageSource, интеграцию с AOP, автоматическое обнаружение BeanPostProcessor и BeanFactoryPostProcessor, а также поддержку eager-инициализации singleton-бинов при старте.
Ключевые отличия
- Инициализация бинов:
BeanFactoryсоздаёт бины лениво (при первомgetBean());ApplicationContextпо умолчанию инициализирует все singleton-бины при старте контекста — ошибки конфигурации обнаруживаются сразу. - Автообнаружение постпроцессоров: В
BeanFactoryнужно вручную регистрироватьBeanPostProcessor;ApplicationContextсканирует контейнер автоматически. - События: Только
ApplicationContextподдерживаетApplicationEvent/@EventListener. - MessageSource / i18n: Встроен только в
ApplicationContext. - Environment и PropertySources: Абстракция
Environment(profiles, properties) доступна черезApplicationContext.
Пример: ручное использование BeanFactory
// Низкоуровневый подход — крайне редко нужен в реальных проектах
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(new ClassPathResource("beans.xml"));
// BeanPostProcessor-ы НЕ применяются автоматически!
factory.addBeanPostProcessor(new AutowiredAnnotationBeanPostProcessor());
MyService service = factory.getBean(MyService.class);
Пример: стандартный ApplicationContext
// В Spring Boot это делается автоматически через SpringApplication.run()
@SpringBootApplication
public class App {
public static void main(String[] args) {
ConfigurableApplicationContext ctx = SpringApplication.run(App.class, args);
// Публикация события
ctx.publishEvent(new UserRegisteredEvent(ctx, userId));
// i18n
String msg = ctx.getMessage("welcome.message", null, Locale.ENGLISH);
}
}
// Получение Environment для работы с профилями
@Component
public class FeatureToggle {
@Autowired
private Environment env;
public boolean isPremiumEnabled() {
return env.acceptsProfiles(Profiles.of("premium"));
}
}
Когда использовать BeanFactory
BeanFactory применяется в крайне ограниченных сценариях: встраиваемые системы с очень ограниченной памятью, тесты с изоляцией на уровне контейнера, или плагинные системы, где нужен полный контроль над жизненным циклом. В 99% случаев правильный выбор — ApplicationContext.
Подводные камни
- При использовании
BeanFactoryнапрямую@Autowired,@Valueи@PostConstructне работают без явной регистрацииAutowiredAnnotationBeanPostProcessorиCommonAnnotationBeanPostProcessor. BeanFactoryне вызывает destroy-методы (@PreDestroy,DisposableBean) автоматически — нужно явно вызыватьdestroySingletons().- Ленивая инициализация в
BeanFactoryмаскирует ошибки конфигурации до первого использования бина в рантайме. - Попытка инжектировать
ApplicationContext-специфичные абстракции (например,ApplicationEventPublisher) в контекст, созданный какBeanFactory, приведёт кNoSuchBeanDefinitionException. - Иерархия контекстов (parent/child
ApplicationContextв Spring MVC) — бин из дочернего контекста не виден в родительском, но видит родительский. Это частый источник ошибок с транзакциями. - Профили (
@Profile) работают только черезEnvironmentвApplicationContext; в bareBeanFactoryпрофили не применяются. - Не путать
BeanFactoryсFactoryBean— последний является бином, который сам создаёт другие объекты (паттерн Factory).
Common mistakes
- Путать термин «beanfactory applicationcontext» с соседним механизмом Spring Framework.
- Не называть границу lifecycle, transaction, thread или request для «beanfactory applicationcontext».
- Игнорировать production-эффекты «beanfactory applicationcontext»: latency, SQL shape, memory, security или observability.
What the interviewer is testing
- Попросить объяснить механизм «beanfactory applicationcontext» на минимальном примере.
- Проверить, видит ли кандидат failure mode и диагностику для «beanfactory applicationcontext».
- Уточнить, какие настройки или API меняют «beanfactory applicationcontext» в реальном сервисе.