Partner – Microsoft – NPI (cat= Spring)
announcement - icon

Azure Spring Apps is a fully managed service from Microsoft (built in collaboration with VMware), focused on building and deploying Spring Boot applications on Azure Cloud without worrying about Kubernetes.

And, the Enterprise plan comes with some interesting features, such as commercial Spring runtime support, a 99.95% SLA and some deep discounts (up to 47%) when you are ready for production.

>> Learn more and deploy your first Spring Boot app to Azure.

You can also ask questions and leave feedback on the Azure Spring Apps GitHub page.

1. Overview

The Spring Framework comes with two IOC containers – BeanFactory and ApplicationContext. The BeanFactory is the most basic version of IOC containers, and the ApplicationContext extends the features of BeanFactory.

In this quick tutorial, we’ll understand the significant differences between these two IOC containers with practical examples.

2. Lazy Loading vs. Eager Loading

BeanFactory loads beans on-demand, while ApplicationContext loads all beans at startup. Thus, BeanFactory is lightweight as compared to ApplicationContext. Let’s understand it with an example.

2.1. Lazy Loading With BeanFactory

Let’s suppose we have a singleton bean class called Student with one method:

public class Student {
    public static boolean isBeanInstantiated = false;

    public void postConstruct() {

    //standard setters and getters

We’ll define the postConstruct() method as the init-method in our BeanFactory configuration file, ioc-container-difference-example.xml:

<bean id="student" class="com.baeldung.ioccontainer.bean.Student" init-method="postConstruct"/>

Now, let’s write a test case that creates a BeanFactory to check if it loads the Student bean:

public void whenBFInitialized_thenStudentNotInitialized() {
    Resource res = new ClassPathResource("ioc-container-difference-example.xml");
    BeanFactory factory = new XmlBeanFactory(res);

Here, the Student object is not initialized. In other words, only the BeanFactory is initialized. The beans defined in our BeanFactory will be loaded only when we explicitly call the getBean() method.

Let’s check the initialization of our Student bean where we’re manually calling the getBean() method:

public void whenBFInitialized_thenStudentInitialized() {
    Resource res = new ClassPathResource("ioc-container-difference-example.xml");
    BeanFactory factory = new XmlBeanFactory(res);
    Student student = (Student) factory.getBean("student");


Here, the Student bean loads successfully. Hence, the BeanFactory only loads the bean when it is required.

2.2. Eager Loading With ApplicationContext

Now, let’s use ApplicationContext in the place of BeanFactory.

We’ll only define ApplicationContext, and it will load all the beans instantly by using an eager-loading strategy:

public void whenAppContInitialized_thenStudentInitialized() {
    ApplicationContext context = new ClassPathXmlApplicationContext("ioc-container-difference-example.xml");

Here, the Student object is created even though we have not called the getBean() method.

ApplicationContext is considered a heavy IOC container because its eager-loading strategy loads all the beans at startup. BeanFactory is lightweight by comparison and could be handy in memory-constrained systems. Nevertheless, we’ll see in the next sections why ApplicationContext is preferred for most use cases.

3. Enterprise Application Features

ApplicationContext enhances BeanFactory in a more framework-oriented style and provides several features that are suitable for enterprise applications.

For instance, it provides messaging (i18n or internationalization) functionality, event publication functionality, annotation-based dependency injection, and easy integration with Spring AOP features.

Apart from this, the ApplicationContext supports almost all types of bean scopes, but the BeanFactory only supports two scopes — Singleton and Prototype. Therefore, it’s always preferable to use ApplicationContext when building complex enterprise applications.

4. Automatic Registration of BeanFactoryPostProcessor and BeanPostProcessor

The ApplicationContext automatically registers BeanFactoryPostProcessor and BeanPostProcessor at startup. On the other hand, the BeanFactory does not register these interfaces automatically.

4.1. Registration in BeanFactory

To understand, let’s write two classes.

Firstly, we have the CustomBeanFactoryPostProcessor class, which implements the BeanFactoryPostProcessor:

public class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    private static boolean isBeanFactoryPostProcessorRegistered = false;
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory){

    // standard setters and getters

Here, we’ve overridden the postProcessBeanFactory() method to check its registration.

Secondly, we have another class, CustomBeanPostProcessor, which implements BeanPostProcessor:

public class CustomBeanPostProcessor implements BeanPostProcessor {
    private static boolean isBeanPostProcessorRegistered = false;
    public Object postProcessBeforeInitialization(Object bean, String beanName){
        return bean;

    //standard setters and getters

Here, we’ve overridden the postProcessBeforeInitialization() method to check its registration.

Also, we’ve configured both the classes in our ioc-container-difference-example.xml configuration file:

<bean id="customBeanPostProcessor" 
  class="com.baeldung.ioccontainer.bean.CustomBeanPostProcessor" />
<bean id="customBeanFactoryPostProcessor" 
  class="com.baeldung.ioccontainer.bean.CustomBeanFactoryPostProcessor" />

Let’s see a test case to check whether these two classes are registered automatically during startup:

public void whenBFInitialized_thenBFPProcessorAndBPProcessorNotRegAutomatically() {
    Resource res = new ClassPathResource("ioc-container-difference-example.xml");
    ConfigurableListableBeanFactory factory = new XmlBeanFactory(res);


As we can see from our test, automatic registration did not happen.

Now, let’s see a test case that manually adds them in the BeanFactory:

public void whenBFPostProcessorAndBPProcessorRegisteredManually_thenReturnTrue() {
    Resource res = new ClassPathResource("ioc-container-difference-example.xml");
    ConfigurableListableBeanFactory factory = new XmlBeanFactory(res);

    CustomBeanFactoryPostProcessor beanFactoryPostProcessor 
      = new CustomBeanFactoryPostProcessor();

    CustomBeanPostProcessor beanPostProcessor = new CustomBeanPostProcessor();
    Student student = (Student) factory.getBean("student");

Here, we used the postProcessBeanFactory() method to register CustomBeanFactoryPostProcessor and the addBeanPostProcessor() method to register CustomBeanPostProcessor. Both of them register successfully in this case.

4.2. Registration in ApplicationContext

As we noted earlier, ApplicationContext registers both the classes automatically without writing additional code.

Let’s verify this behavior in a unit test:

public void whenAppContInitialized_thenBFPostProcessorAndBPostProcessorRegisteredAutomatically() {
    ApplicationContext context 
      = new ClassPathXmlApplicationContext("ioc-container-difference-example.xml");


As we can see, automatic registration of both classes is successful in this case.

Therefore, it’s always advisable to use ApplicationContext because Spring 2.0 (and above) heavily uses BeanPostProcessor.

It’s also worth noting that if you’re using the plain BeanFactory, then features like transactions and AOP will not take effect (at least not without writing extra lines of code). This may lead to confusion because nothing will look wrong with the configuration.

5. Conclusion

In this article, we’ve seen the key differences between ApplicationContext and BeanFactory with practical examples.

The ApplicationContext comes with advanced features, including several that are geared towards enterprise applications, while the BeanFactory comes with only basic features. Therefore, it’s generally recommended to use the ApplicationContext, and we should use BeanFactory only when memory consumption is critical.

As always, the code for the article is available over on GitHub.

Course – LS (cat=Spring)

Get started with Spring and Spring Boot, through the Learn Spring course:

res – REST with Spring (eBook) (everywhere)
Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.