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
DefaultListableBeanFactoryimplementation is a key delegate inside the higher‑level
GenericApplicationContextcontainer.
BeanFactory and related interfaces such as
BeanFactoryAware,
InitializingBean, and
DisposableBeanserve 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
BeanDefinitionmetadata. In other words, the core BeanFactory API itself does not process annotations; extensions like
BeanPostProcessorimplement AOP and other features.
BeanFactory vs ApplicationContext
Unless you have a compelling reason, you should use
ApplicationContext—specifically
GenericApplicationContextand 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
ApplicationContextincludes 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
DefaultListableBeanFactoryis unaware of any special beans.
For features like annotation processing and AOP proxies, the
BeanPostProcessorextension 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
BeanPostProcessorwhen using a plain
DefaultListableBeanFactory, you must register it programmatically:
<code>DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
// populate the factory with bean definitions
factory.addBeanPostProcessor(new AutowiredAnnotationBeanPostProcessor());
factory.addBeanPostProcessor(new MyBeanPostProcessor());
// now the factory can be started
</code>To apply a BeanFactory post‑processor, you need to invoke the appropriate methods, for example:
<code>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);
</code>Both manual registration approaches are cumbersome, which explains why ApplicationContext variants are preferred in typical enterprise Spring applications, especially when relying on
BeanFactoryPostProcessorand
BeanPostProcessorinstances to extend container functionality.
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.