1. Overview
In this article, we will discuss Spring bean instantiation.
2. What is bean in Java spring
The spring beans are instance objects that are managed by the Spring container, meaning the Spring container instantiates, configures, and assembles those instance objects from where you can get them later.
3. Bean definition
The configuration metadata provides instructions to the Spring container on what objects to instantiate, configure and assemble. To put it another way, you can tell the Spring container to instantiate, configure, and assemble the objects in your application using the configuration metadata.
Spring configuration comprises at least one or more than one bean definition that the container must manage. These bean definitions correspond to the actual objects that make up your application.
A bean definition is a formula to create one or more objects. Therefore, the Spring container checks the bean definition and creates the actual bean object.
For example, below is a bean definition that instructs the Spring container to create an instance of type com.tedblob.SampleBean
. So, you must specify the type or class of object to be instantiated in the class
attribute.
<bean id="sampleBean" class="com.tedblob.SampleBean" />
4. Bean instantiation
We can do bean instantiation using the following ways:
- a constructor
- a static factory method
- an instance factory method
4.1 Bean Instantiation using a constructor
You can create a bean using the constructor approach. The class being instantiated does not need to implement any specific interfaces or to be coded specifically. Simply specifying the bean class in the bean definition should be enough. It uses the default (no-args) constructor if doesn’t specify constructor arguments.
4.1.1. Constructor instantiation example
Let’s take the below bean definition – XML configuration. Here, we have specified the class attribute with the fully qualified class name for which we need the bean.
<bean id="student" class="com.tedblob.Student"/>
4.2. Bean instantiation using Static factory method
When you use constructor-based instantiation, you will specify the exact class of the bean object to be created in the class attribute of <bean>.
Suppose you want the class method to decide which bean to instantiate. You can achieve it using the static factory method. A Factory Method is a static method inside the class for creating an object. Therefore, the Spring container creates the object by calling the factory method.
The factory method must be static to allow the Spring container to invoke it.
4.2.1. Static factory example
It will throw compilation error “Exception encountered during context initialization – cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘beanName’ defined in class path resource [beans.xml]: No matching factory method found: factory method ‘factoryMethod()’. Check that a method with the specified name exists and that it is static.”
Let’s take an example. The below Student
class has a static factory method createInstance
. Note that the factory method returns the instance of Subject
class but not Student
class. But you can pass the instance of any other class in the factory method or the enclosing class.
package com.tedblob.beans; public class Student { private static Subject subject = new Subject(); private Student() {} public static Subject createInstance() { System.out.println("createInstance Subject"); return subject; } public String getName() { return "Student class"; } } package com.tedblob.beans; public class Subject { public String getName() { return "Subject class"; } }
Note the below bean definition does not specify the type (class) of the returned object but only the class containing the factory method specified using the class
attribute.
<bean id="subject" class="com.tedblob.beans.Student" factory-method="createInstance"> </bean>
You use the class
attribute to specify the class containing the static
factory method and the factory-method
attribute to specify the name of the factory method itself.
public class ClassPathXmlApplicationContextExample { public static void main(String[] args) { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/beans.xml"); Subject exampleClass = context.getBean(Subject.class); System.out.println(exampleClass.getName()); } }
Later, you can invoke the members of the subject
bean from your code.
4.3. Bean Instantiation using an instance factory method
Similar to the above static factory method, instantiation with an instance factory method invokes a non-static method of an existing bean from the container to create a new bean.
4.3.1. Instance factory example
Let’s take the same Student
example discussed in the above section. The factory method createInstance
is not static here because we are going to access it using the student
bean instance.
package com.tedblob.beans; public class Student { private static Subject subject = new Subject(); public Subject createInstance() { System.out.println("createInstance Subject"); return subject; } public String getName() { return "Student class"; } } public class Subject { public String getName() { return "Subject class"; } }
First, we create a bean definition for the Student
class. So, the Spring container creates a student
bean instance. Next, we have the bean definition for the Subject
class. Note the student
bean
We haven’t used the class
attribute, and in the factory-bean
attribute, we specified the student
bean. Note the bean that has the factory method should exist in the current (or parent/ancestor) container. The attribute factory-method
contains the name of the factory method itself.
<bean id="student" class="com.tedblob.Student"/> <bean id="subject" factory-bean="student" factory-method="createInstance"> </bean>
4.3.1. Bean instantiation using more than one factory method
The factory class can have more than one factory method.
Let’s take an example. In the below code, the Student
class has two instance factory methods: one for Subject
bean and another for Professor
bean instantiation.
package com.tedblob.beans; public class Student { private static Subject subject = new Subject(); private static Professor professor = new Professor(); public Subject createInstance() { System.out.println("createInstance Subject"); return subject; } public Professor createProfessorInstance() { System.out.println("createInstance Professor"); return professor; } public String getName() { return "Student class"; } }
There would be two separate bean definitions for each factory method in the configuration file.
<bean id="student" class="com.tedblob.Student"/> <bean id="subject" factory-bean="student" factory-method="createInstance"> </bean> <bean id="subject" factory-bean="student" factory-method="createInstance"> </bean>
4.4. Bean instantiation of Inner static class
You can create a bean for your inner static class. Let’s see an example. The below Student
class has a static inner class Information
.
package com.tedblob.beans; public class Student { public static class Information { public String getName() { return "Student$Information class"; } } public String getName() { return "Student class"; } }
You can create a bean for this Information
class using the below bean definition. Notice the use of the $
character in the class name to separate the inner class name from the outer class name.
<bean id="student" class="com.tedblob.Student"/> <bean id="studentInfo" class="com.tedblob.Student$Information"/>
5. Conclusion
In this article, we have gone through the Bean instantiation along with examples. We also recommend you to see our other Spring articles.
Pingback: Kotlin Spring constructor injection with examples - TedBlob
Pingback: Kotlin spring dependency injection: Constructor and setter based - TedBlob
Pingback: Get context from non spring class - ApplicationContextAware - TedBlob
Pingback: Use Spring @Autowired in Kotlin - TedBlob
Pingback: Spring @ConfigurationProperties autowired - TedBlob
Pingback: Kotlin Spring @ConfigurationProperties - TedBlob
Pingback: Spring ConfigurationProperties Kotlin data class - TedBlob
Pingback: @EnableConfigurationProperties - TedBlob
Pingback: ApplicationContext vs BeanFactory - TedBlob
Pingback: xmlbeanfactory deprecated - TedBlob
Pingback: Spring BeanFactory - TedBlob
Pingback: DefaultListableBeanFactory - TedBlob
Pingback: Spring register bean programmatically - TedBlob
Pingback: Spring Boot remove bean from context - TedBlob
Pingback: depends-on Spring XML - TedBlob
Pingback: Spring Application scope vs Singleton - TedBlob