Spring BeanFactory vs ApplicationContext

Spring BeanFactory vs ApplicationContext

0 Comments

Last Updated on September 6, 2021 by jt

The Spring Ioc container is at the core of the Spring Framework. BeanFactory and ApplicationContext provide implementations of the IoC container. Both BeanFactory and ApplicationContext are interfaces and there are several implementations that come out of the box with Spring.

In this post, I will explain the differences between BeanFactory and ApplicationContext.

Major Differences between BeanFactory and ApplicationContext

Following are few differences :

  • BeanFactory instantiates a bean when you call the getBean() method while ApplicationContext instantiates
    a Singleton bean as soon as the container starts.
  • BeanFactory supports lazy loading unlike ApplicationContext that support default eager loading.
  • BeanFactory doesn’t provide support for internationalization but ApplicationContext provides support for it.
  • XMLBeanFactory implements BeanFactory whereas FileSystemXmlApplicationContext, ClassPathXmlApplicationContext and AnnotationConfigWebApplicationContex implements ApplicationContext.

Here is an example of how to get a bean through both ways.

Maven Dependency to define Spring Injection Container

To work with beans and bean instantiation, you will require spring-context dependency to add in your pom.xml file.

  
<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-context</artifactId>
   <version>5.3.5</version>
</dependency>

In the example domain, I have taken two POJO classes – Book and BookPublisher.

The code for BookPublisher class is this.

BookPublisher.java

@Component
public class BookPublisher {

    private int publisherId;
    private String firstName;
    private String lastName;
//No-args Constructor
//Parametrized-Constructor
//Getters and Setters
//to-String method
}

The BookPublisher class is annotated with @Component annotation which allows Spring to automatically detect your custom beans.

The other POJO class is Book which has a BookPublisher associated with it.

This is the code for Book class.

Book.java

@Component
public class Book {
    private String bookTitle;
    private String bookType;
    BookPublisher bookPublisher;
//No-args Constructor
//Parametrized Constructor
//Getters and Setters
//to-String() method
}

Note: It is also annotated with @Component.

Configuring the beans for both Spring Containers

The code for the BeanConfiguration class is this.

BeanConfiguration.java

@Configuration
public class BeanConfiguration {

    @Bean(name = "book")
    public Book getBookDetails() {
        Book book = new Book();
        book.setBookTitle("Application Context vs Spring Bean Factory");
        book.setBookType("Reference");
        book.setBookPublisher(getPublisherDetails());
        return book;
    }

    @Bean(name = "bookPublisher")
    public BookPublisher getPublisherDetails() {
        BookPublisher bookPublisher = new BookPublisher();
        bookPublisher.setPublisherId(101);
        bookPublisher.setFirstName("Henry");
        bookPublisher.setLastName("SFG");
        return bookPublisher;
    }
}

This class is annotated with @Configuration annotation. It declares Spring beans using the @Bean annotations on methods.

The Spring container process these methods to generate bean definitions and service requests for those beans at runtime.

There are two @Bean annotated methods namely getBookDetails() and getPublisherDetails() which return book and bookPublisher objects respectively.

Configuring the BeanFactory with XML

Here, I have configured the BeanFactory with XML and created a file beans.xml under resources folder.

beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans">
    <!-- Setter injection-->
    <bean id="book" class="org.springframework.guru.domain.Book">
        <property name="bookPublisher">
            <bean class="org.springframework.guru.domain.BookPublisher">
                <property name="publisherId" value ="101"/>
                <property name="firstName" value="Joseph"/>
                <property name="lastName" value="Ray"/>
            </bean>
        </property>
    </bean>
</beans>

The beans configured are created with the configuration metadata that you supply to the container, here in beans.xml file.

Line 5 represents a simple bean definition with id and class attributes.

The property attribute in Line 6 is used to inject the dependencies.

Running the Application

This is the code for the Main class.

DemoApplication.java

public class DemoApplication {
	public static void main(String[] args) {

        //using bean Factory
	XmlBeanFactory factory=new XmlBeanFactory(new ClassPathResource("beans.xml"));
        System.out.println(factory);
        Book book= (Book) factory.getBean("book");
        System.out.println(book.getBookPublisher());

         //Using ApplicationContext
         ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml");
          System.out.println(context);
          Book book1= (Book) context.getBean("book");
          System.out.println(book1.getBookPublisher());

         //Annotation-configuration
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext();
	annotationConfigApplicationContext.register(BeanConfiguration.class);
        annotationConfigApplicationContext.refresh();
	Book book1 = (Book) annotationConfigApplicationContext.getBean("book");
	System.out.println(book1);
	}
}

In Line 5, you create a factory object using the framework APIXmlBeanFactory() to create the factory bean. The ClassPathResource() API is used to load the bean configuration file available in CLASSPATH.

The XmlBeanFactory() API takes care of creating and initializing all the objects, i.e. beans mentioned in the configuration file.

In Line 6, the required bean is obtained using getBean() method of the created bean factory object.

This method uses bean Id to return a generic object, which finally can be cast to the actual object.
Once you have the object, you can use this object to call any class method.

The ApplicationContext includes all functionality of the BeanFactory, therefore it is generally recommended over BeanFactory.

Line 10 uses the framework ClassPathXmlApplicationContext to create factory object to load the bean configuration file from the given path.

beanfactory vs applicationcontext

In the above console output figure, you can clearly make out the difference between the two of them.

The BeanFactory instantiates a bean when you call the getBean() method.
Whereas the ApplicationContext instantiates a Singleton bean as soon as the container is started.

Also, the BeanFactory implementations cannot be used with annotation configuration. I have therefore, used AnnotationConfigApplicationContext one of the implementation of ApplicationContext to call the getBean() method.

The proceeding figure shows the console output.

annotation based configuration

Summary

The BeanFactory is usually preferred where the resources are limited like mobile devices or applet-based applications. Thus, use an ApplicationContext unless you have a good reason for not doing so.

You can find the source code of this post on Github.

For in-depth knowledge on Spring Framework concepts, you can check my Udemy Best Seller Course on Spring Framework 5: Beginner to Guru

Udemy Course on Spring Framework

About SFG Contributor

Staff writer account for Spring Framework Guru

    You May Also Like

    Leave a Reply

    Your email address will not be published. Required fields are marked *

    This site uses Akismet to reduce spam. Learn how your comment data is processed.