Spring BeanFactory vs ApplicationContext
0 CommentsThe 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 thegetBean()
method whileApplicationContext
instantiates
a Singleton bean as soon as the container starts.BeanFactory
supports lazy loading unlikeApplicationContext
that support default eager loading.BeanFactory
doesn’t provide support for internationalization butApplicationContext
provides support for it.XMLBeanFactory
implementsBeanFactory
whereasFileSystemXmlApplicationContext
,ClassPathXmlApplicationContext
andAnnotationConfigWebApplicationContex
implementsApplicationContext
.
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.
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.
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