When to Choose BeanFactory vs ApplicationContext in Spring 5?
This article explains the core differences between Spring's BeanFactory and ApplicationContext, why ApplicationContext is generally preferred, and how to manually register BeanPostProcessors when using a plain DefaultListableBeanFactory.
Environment: Spring 5.3.10
BeanFactory
The BeanFactory API provides the foundation for Spring's IoC container. Its main contract is used for integration with other parts of Spring and third‑party frameworks. The DefaultListableBeanFactory implementation is a key delegate inside the higher‑level GenericApplicationContext container.
BeanFactory and related interfaces such as BeanFactoryAware, InitializingBean, and DisposableBean serve as important integration points. They work without annotations or reflection, allowing efficient interaction between the container and its components. Application‑level beans can also use these callbacks, though declarative dependency injection via annotations or configuration is more common.
Note that the core BeanFactory API does not handle configuration design or component annotations. All such functionality is introduced through extensions (e.g., XmlBeanDefinitionReader, AutowiredAnnotationBeanPostProcessor) that operate on shared BeanDefinition metadata. In other words, the core BeanFactory API itself does not process annotations; extensions like BeanPostProcessor implement AOP and other features.
BeanFactory vs ApplicationContext
Unless you have a compelling reason, you should use ApplicationContext —specifically GenericApplicationContext and its subclass AnnotationConfigApplicationContext —as the common implementation for a custom startup container. These are the primary entry points of the Spring core container for loading configuration files, triggering class‑path scanning, programmatically registering bean definitions and annotated classes, and (since 5.0) registering functional bean definitions.
Because ApplicationContext includes all BeanFactory capabilities, it is usually recommended not to use a plain BeanFactory unless you need complete control over bean handling. In an ApplicationContext, special beans such as post‑processors are detected automatically by convention (by bean name or type). A plain DefaultListableBeanFactory is unaware of any special beans.
For features like annotation processing and AOP proxies, the BeanPostProcessor extension point is essential. If you use only a plain DefaultListableBeanFactory, these post‑processors are not detected or activated by default, which can be confusing because the bean configuration itself may be correct. You would need additional setup to fully configure the container, and annotation processing/AOP will not work unless you manually register the required post‑processors.
The following table summarizes the capabilities of BeanFactory and ApplicationContext (described in prose):
Bean instantiation: both support.
Lifecycle management: only ApplicationContext provides.
Automatic registration of BeanPostProcessor: only ApplicationContext.
Automatic registration of BeanFactoryPostProcessor: only ApplicationContext.
Convenient message source access (for i18n): only ApplicationContext.
Built‑in ApplicationEvent publishing: only ApplicationContext.
Manual Registration
To apply a BeanPostProcessor when using a plain DefaultListableBeanFactory, you must register it programmatically:
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
// populate the factory with bean definitions
factory.addBeanPostProcessor(new AutowiredAnnotationBeanPostProcessor());
factory.addBeanPostProcessor(new MyBeanPostProcessor());
// now the factory can be startedTo apply a BeanFactory post‑processor, you need to invoke the appropriate methods, for example:
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(new FileSystemResource("beans.xml"));
// load properties
PropertySourcesPlaceholderConfigurer cfg = new PropertySourcesPlaceholderConfigurer();
cfg.setLocation(new FileSystemResource("jdbc.properties"));
cfg.postProcessBeanFactory(factory);Both manual registration approaches are cumbersome, which explains why ApplicationContext variants are preferred in typical enterprise Spring applications, especially when relying on BeanFactoryPostProcessor and BeanPostProcessor instances to extend container functionality.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
