The main purpose of the IOC Containers in the Spring applications is
- To recognize the Spring configuration file and read the data from the Spring Configuration File.
- To recognize the Bean classes and their locations from the Spring Configuration file.
- To create and Manage the Bean objects and Providing bean objects to the Spring Application.
Spring Framework provides the following two types of IOC Containers.
- BeanFactory
- ApplicationContext
BeanFactory
BeanFactory is deprecated in Spring Framework.
In Spring Framework, the BeanFactory is an interface that provides the fundamental mechanism for managing and retrieving beans in a Spring container. It serves as the central registry for holding bean definitions and managing the complete lifecycle of beans, including their instantiation, configuration, and destruction.
BeanFactory is a fundamental or a base container, it is able to perform the fundamental functionalities of the containers like Identify the bean classes , creating objects for the bean classes and supplying these objects to the Spring applications.
In the Spring framework, BeanFactory is an outdated container, it is not supporting the advanced features of the Spring framework like Event handling, Internationalization, Data Validations,….
To represent BeanFactory container in Spring framework, Spring Framework has provided a predefined interface in the form of “org.springframework.beans.factory.BeanFactory”.
Spring Framework has provided an implementation class for the BeanFactory interface in the form of “org.springframework.beans.factory.xml.XmlBeanFactory”.
The BeanFactory is often implemented by various concrete classes in Spring, such as XmlBeanFactory, DefaultListableBeanFactory, and others. However, starting with Spring 3.1, the XmlBeanFactory has been deprecated in favor of using the ApplicationContext interface, which extends the BeanFactory and provides additional features like event propagation, AOP integration, and more.
NOTE – In Spring Framework, XmlBeanFactory class was deprecated in the Spring 3.x version, it was managed by Spring Framework up to its Spring 5.x version, it has been removed from the Spring 6.x version.
XmlBeanFactory
To create an object for the XmlBeanFactory class we have to use the following constructor.
public XmlBeanFactory(Resource resource)
Resource is an object in Spring Framework, it is able to manage all the spring configuration details which we provided in the Spring configuration file and it will supply Spring configuration details to the BeanFactory container in order to create Bean objects.
In Spring Framework , to represent Resource objects, Spring framework has provided a predefined interface in the form of “org.springframework.core.io.Resource”.
Spring framework has provided the following implementation classes for the Resource interface in order to encapsulate the Spring configuration details.
ClasspathResource: It is able to get the spring configuration details from the Spring configuration file available in the classpath.
FileSystemResource: It is able to get the configuration details from the Spring configuration file available in a particular location in the local File system.
InputStreamResource: It is able to get the Spring configuration details which are available in an InputStream object.
ByteArrayResource: It is able to get the Spring configuration details which are available in the form of a byte[].
ServletContextResource: It is able to get the Spring configuration details which are available in the ServletContext object in a particular web application.
PortletContextResource: It is able to get the Spring configuration details which are available in the PortletContext object in a particular web application.
UrlResource: It is able to get the Spring configuration details which are available in a particular URL.
Resource resource = new ClasspathResource(“Spring-Config.xml”);
Beanfactory beanFactory = new XmlBeanFactory(resource);
// Load the bean definitions from the XML configuration file
BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("applicationcontext.xml"));
The XmlBeanFactory is used to load bean definitions from an XML configuration file.
BeanFactory - does lazy loading of beans.
Example using BeanFactory – ClassPathResource
Employee.java
package com.durgasoft.beans;
public class Employee {
private int eno;
private String ename;
private float esal;
private String eaddr;
public int getEno() {
return eno;
}
public void setEno(int eno) {
this.eno = eno;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public float getEsal() {
return esal;
}
public void setEsal(float esal) {
this.esal = esal;
}
public String getEaddr() {
return eaddr;
}
public void setEaddr(String eaddr) {
this.eaddr = eaddr;
}
public void getEmployeDetails(){
System.out.println("Employee Details");
System.out.println("-----------------------");
System.out.println("Employee Number : "+eno);
System.out.println("Employee Name : "+ename);
System.out.println("Employee Salary : "+esal);
System.out.println("Employee Address : "+eaddr);
}
}
Spring-Config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="employee" class="com.durgasoft.beans.Employee">
<property name="eno" value="111"/>
<property name="ename" value="Durga"/>
<property name="esal" value="5000"/>
<property name="eaddr" value="Hyd"/>
</bean>
</beans>
Main.java
import com.durgasoft.beans.Employee;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
public class Main {
public static void main(String[] args) {
Resource resource = new ClassPathResource("Spring-Config.xml");
BeanFactory beanFactory = new XmlBeanFactory(resource);
Employee employee = (Employee) beanFactory.getBean("employee");
employee.getEmployeDetails();
}
}
To check the above application Step by step in the Test application use the following Test class.
import com.durgasoft.beans.Employee;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
public class Main {
public static void main(String[] args)throws Exception {
Resource resource = new ClassPathResource("Spring-Config.xml");
System.out.println(resource.getFilename());
System.out.println("Resource Object Created.....");
System.in.read();
BeanFactory beanFactory = new XmlBeanFactory(resource);
System.out.println("beanFactory Object is Created....");
System.in.read();
Employee employee = (Employee) beanFactory.getBean("employee");
System.out.println("Getting Employee Object....");
System.in.read();
employee.getEmployeDetails();
}
}
In general, in Spring applications, if we use BeanFactory IOC Container then the following actions will be performed in the Test Application.
- When we create a Resource Object, JVM will provide only the metadata of the Spring configuration file in the Resource like Resource File Name, Resource File Location,….
Resource resource = new ClasspathResource(“Spring-Config.xml”);
- When we create a BeanFactory object, BeanFactory will identify the name and location of the Spring configuration file, BeanFactory will load , parse and read the data from the Spring configuration file, BeanFactory will store all the Spring configuration file data in the Resource object.
- When we access
getBean()method on the BeanFactory reference variable , the BeanFactory Container will get the name and location of the respective bean class from the Resource object, BeanFactory will perform loading, Instantiation and initialization of the Bean class , the BeanFactory Container will manage the generated Bean object along with its identity value and The BeanFactory will return the generated Bean object as return value from the getBean() method.
Note: BeanFactory container is following Lazy Loading or Lazy Instantiation of the Bean objects.
Example using BeanFactory – FileSystemResource
Employee.java
package com.durgasoft.beans;
public class Employee {
private int eno;
private String ename;
private float esal;
private String eaddr;
public Employee() {
System.out.println("Employee Bean instantiation.....");
}
public int getEno() {
return eno;
}
public void setEno(int eno) {
this.eno = eno;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public float getEsal() {
return esal;
}
public void setEsal(float esal) {
this.esal = esal;
}
public String getEaddr() {
return eaddr;
}
public void setEaddr(String eaddr) {
this.eaddr = eaddr;
}
public void getEmployeDetails(){
System.out.println("Employee Details");
System.out.println("-----------------------");
System.out.println("Employee Number : "+eno);
System.out.println("Employee Name : "+ename);
System.out.println("Employee Salary : "+esal);
System.out.println("Employee Address : "+eaddr);
}
}
Spring-Config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="employee" class="com.durgasoft.beans.Employee">
<property name="eno" value="111"/>
<property name="ename" value="Durga"/>
<property name="esal" value="5000"/>
<property name="eaddr" value="Hyd"/>
</bean>
</beans>
Main.java
import com.durgasoft.beans.Employee;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
public class Main {
public static void main(String[] args)throws Exception {
Resource resource = new FileSystemResource("/Users/nagoorn/Documents/docs/Spring-Config.xml");
BeanFactory beanFactory = new XmlBeanFactory(resource);
Employee employee = (Employee) beanFactory.getBean("employee");
employee.getEmployeDetails();
}
}
Q) ClassPathResource v/s FileSystemresource?
ClassPathResource is able to find the Spring Configuration file available in the classpath locations[src, resources] existing inside the application.
FileSystemResource is able to find the Spring Configuration file available either in the current application or in the outside of the current application[any location in the System Hard disk].
DefaultListableBeanFactory
DefaultListableBeanFactory is a specific implementation of the BeanFactory interface in the Spring Framework. It extends the more basic AbstractAutowireCapableBeanFactory class and provides additional functionality for handling bean definitions in a Spring IoC container.
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.core.io.ClassPathResource;
public class MyApp {
public static void main(String[] args) {
// Create a DefaultListableBeanFactory
DefaultListableBeanFactory beanFactory =
new DefaultListableBeanFactory();
// Create an XmlBeanDefinitionReader
XmlBeanDefinitionReader reader =
new XmlBeanDefinitionReader(beanFactory);
// Load bean definitions from an XML file
reader.loadBeanDefinitions(
new ClassPathResource("applicationContext.xml"));
// Retrieve a bean by name
MyBean myBean = (MyBean) beanFactory.getBean("myBean");
// Use the bean
myBean.doSomething();
}
}
This way, we can load multiple bean definition/configuration files with the same IoC container.
ApplicationContext IOC Container:
ApplicationContext is a child container to the BeanFactory.
ApplicationContext container is able to perform all the activities of the BeanFactory and it is able to support the advanced features like Event Handling, Data Validations, Internationalization….
To represent ApplicationContext Container in Spring Applications, Spring Framework has provided a predefined interface in the form of “org.springframework.context.ApplicationContext” and the Spring Framework has provided the following implementation classes for the ApplicationContext interface.
ClassPathXmlApplicationContextFileSystemXmlApplicationContextWebXmlApplicationContext
Example – Simple Maven project with XML Configuration
Step 1 – Create a Maven project in Eclipse IDE
Specify the details as needed :
Once the project is created, you see project structure like this :
src/main/java – all Java source files will be here.src/main/resources – all configuration files which act like supporting files to the main application project.src/test/java – all JUnit or unit testing files will go here.
pom.xml – maven file for specifying dependencies.
Step 2 – add spring dependencies to the Maven project
Adding Spring Context dependency to the project using dependency :
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.24</version>
</dependency>
</dependencies>
All the dependencies have been added :
Step 3 – Creating POJO classes
DeliveryService.java
package com.rndayala.java;
public interface DeliveryService
{
boolean courierService(double amount);
}
BlueDart.java
package com.rndayala.java;
public class BlueDart implements DeliveryService {
@Override
public boolean courierService(double amount) {
System.out.println("Delivery Service using BlueDart courier service : " + amount);
return true;
}
}
FedEx.java
package com.rndayala.java;
public class FedEx implements DeliveryService {
@Override
public boolean courierService(double amount) {
System.out.println("Delivery Service using FedEx courier service : " + amount);
return true;
}
}
Amazon.java
package com.rndayala.java;
// Loose coupling example
// target class
public class Amazon {
// FedEx, BlueDart, FirstFlight -- these are all dependent objects
private DeliveryService service;
public void setService(DeliveryService service) {
this.service = service;
}
public boolean initiateDelivery(double amount) {
return service.courierService(amount);
}
}
Step 4 – create Spring configuration XML file
XmlConfiguration to talk to Spring Framework.
Go to the link https://docs.spring.io/spring-framework/docs/4.2.x/spring-framework-reference/html/xsd-configuration.html
Adding schema to the xml configuration file : applicationcontext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- bean definitions here -->
</beans>
About Spring Beans
Now add beans definitions to the xml configuration file.
In Spring Framework, a “bean” is a fundamental building block. In simple terms, a bean is an object that is managed by the Spring IoC (Inversion of Control) container. The IoC container is responsible for instantiating, configuring, and managing these beans throughout their lifecycle.
Key characteristics of a Spring bean:
1. Java Objects: Beans are simply instances of Java objects, often representing the various components of an application.
2. Managed by Spring: Spring IoC container manages the lifecycle of beans, handling their creation, configuration, and destruction.
3. Configurable: Beans are typically defined in the Spring configuration file (often XML or using annotations) with details such as class information, dependencies, and other configurations.
4. Dependency Injection: Spring promotes the use of dependency injection, where the dependencies of a bean are injected into it rather than the bean creating or managing its dependencies. This helps in creating loosely coupled and easily testable components.5. Singleton by Default: By default, Spring beans are singletons, meaning that only one instance of the bean is created and shared across the application.
Example :
<bean id="bluedart" class="com.rndayala.springcore.beans.BlueDart">
<!-- Configurations and dependencies go here -->
</bean>
<bean id="firstflight" class="com.rndayala.springcore.beans.FirstFlight"/>
<bean id="fedex" class="com.rndayala.springcore.beans.FedEx"/>
<bean id="amazon" class="com.rndayala.springcore.beans.Amazon"/>
id: The id attribute is aunique identifierfor the bean within the Spring IoC container. It serves as a name or label that can be used to reference and retrieve the bean when needed. The id should be unique among all the beans defined in the application context.
class: The class attribute specifies the fully qualified class name of the Java class that represents the bean. It tells the Spring IoC container which class to instantiate when creating the bean.
Together, the id and class attributes uniquely identify and specify the type of the bean within the Spring IoC container. The container uses this information to manage the lifecycle of the bean and provide it as needed throughout the application.
Step 5 – Create Main test class
package com.rndayala.springcore.main;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class LaunchApp {
public static void main(String[] args) {
// activating Spring IoC container
ApplicationContext context =
new ClassPathXmlApplicationContext("applicationcontext.xml");
}
}
Just loading the Spring configuration using ApplicationContext, Spring container will load all the bean classes and then, their objects are created. [Eager initialization]
Console output :
BlueDart class is loaded.
BlueDart class is instantiated
FirstFlight class is loaded.
FirstFlight class is instantiated
FedEx class is loaded.
FedEx class is instantiated
Amazon class is loaded.
Amazon class is instantiated.
Q) Beanfactory v/s ApplicationContext?
1. BeanFactory is a Fundamental Container, it is able to provide only the basic functionalities of the Container like Bean Management that includes loading and instantiating Bean objects.
ApplicationContext is an extension of the BeanFactory , it is able to provide some advanced features of the Containers like Internationalization, Data Validations, Event Handling,… along with the Bean management.
2. BeanFactory is not supported to integrate the AOP services like Security, JTA,…
ApplicationContext is supporting the integration of the AOP services like Security, JTA,…
3. Beanfactory is not suitable for the web applications, it is suitable for only the simple Standalone applications.
ApplicationContext is suitable for all the types of the applications like Standalone Applications, Web applications, Distributed applications, Database related applications….
4. BeanFactory is able to create Bean objects after its startup and after getting the first request from the Test Application for the bean, It is called Lazy Instantiation or Lazy initialization.
ApplicationContext will create Bean objects at its startup time, it is called eager or early instantiation / initialization.
5. BeanFactory is supporting the scopes like Singleton and Prototype.
ApplicationContext is supporting all the SCops of the Spring framework like Singleton, Prototype, request, session, WebSocket, GlobalSession,…
6. Beanfactory is an outdated Container, not suitable for the peasant application requirements.
ApplicationContext is not an outdated Container, it is suitable for the present application requirement.
Example on the ClassPathXmlApplicationContext
Product.java
package com.durgasoft.beans;
public class Product {
private int productId;
private String productName;
private int productPrice;
private String mfgDate;
private String exprDate;
public int getProductId() {
return productId;
}
public void setProductId(int productId) {
this.productId = productId;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public int getProductPrice() {
return productPrice;
}
public void setProductPrice(int productPrice) {
this.productPrice = productPrice;
}
public String getMfgDate() {
return mfgDate;
}
public void setMfgDate(String mfgDate) {
this.mfgDate = mfgDate;
}
public String getExprDate() {
return exprDate;
}
public void setExprDate(String exprDate) {
this.exprDate = exprDate;
}
public void getProductDetails(){
System.out.println("Product Details");
System.out.println("----------------------");
System.out.println("Product Id : "+productId);
System.out.println("Product Name : "+productName);
System.out.println("Product Price : "+productPrice);
System.out.println("Mfg Date : "+mfgDate);
System.out.println("Expr Date : "+exprDate);
}
}
Spring-Config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="product" class="com.durgasoft.beans.Product">
<property name="productId" value="111"/>
<property name="productName" value="Mobile"/>
<property name="productPrice" value="25000"/>
<property name="mfgDate" value="12-10-2022"/>
<property name="exprDate" value="12-10-2025"/>
</bean>
</beans>
Main.java
import com.durgasoft.beans.Product;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {
public static void main(String[] args) {
ApplicationContext applicationContext =
new ClassPathXmlApplicationContext("Spring-Config.xml");
Product product = applicationContext.getBean(Product.class);
product.getProductDetails();
}
}
Example on the FileSystemXmlApplication
Main.java
import com.durgasoft.beans.Product;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class Main {
public static void main(String[] args) {
ApplicationContext applicationContext =
new FileSystemXmlApplicationContext("E:/documents/Spring-Config.xml");
Product product = (Product) applicationContext.getBean("product");
product.getProductDetails();
}
}