Written by Rod Johnson, Spring framework was first released under the Apache 2.0 license in June 2003. It is the most common application development platform for enterprise Java. This open-source Java platform is used by millions of users across the globe to build high-performing, conveniently verifiable, and reusable code.
What is Spring Bean?
An object that is instantiated, gathered, and otherwise managed by a Spring IoC container is called a bean. The configuration metadata that you provide to the container is used to build these beans. The configuration metadata that you provide to the container is used to build these beans. The configuration metadata contained in the bean specification is required for the container to know how to make a bean, details of bean’s lifespan and timeline and its dependencies.
Bean Scopes in Spring:
The scope of a bean corresponds to the lifecycle of a bean, which includes when the object is instantiated, how long it lives, and how many objects are made for that bean over time. Regulated by the spring container, it basically manages the bean instance formation.
Five different scopes for a bean are included in the spring framework. Two of them are available for both IoC and Spring-MVC containers while the rest three are only usable in the context of web-aware Spring ApplicationContext. The following are the five different scopes for a bean:
Singleton Scope:
If the bean's scope is singleton, only one object of that bean will be created per Spring IoC container, and that object will be shared across all requests, i.e., the same instance is returned each time it is injected. When a bean's scope is declared as singleton, the spring IOC container first checks if an object of that bean has already been generated before making a new request for it. The IOC container returns the same instance if it has already been created; otherwise, it generates a new instance of that bean only on the first request.
Example:
First of all, we create a bean in our example.
// JAVA CODE
package bean;
public class Sample{
public int value;
//A setter method to set the value
public void setValue(int data)
{
this.value = data;
}
//A getter method to get the value
public String getValue()
{
return value;
}
}
Then we write the configuration file “SampleXML.xml” and configure the bean that we just created.
<!-- XML CODE -->
<!DOCTYPE beans PUBLIC
"-//SPRING//DTD BEAN 2.0//EN"
"http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
< bean
id = "id1"
class= "bean.Sample"
scope = "singleton" / >
</beans>
Then we write a driver class “User.java” which can request the above bean.
// JAVA CODE
package driver;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import bean.Sample;
public class User {
public static void main(String[] args)
{
// Loading the XML configuration file
ApplicationContext appContext = new ClassPathXmlApplicationContext( "resources/SampleXML.xml");
Sample obj1 = (Sample)appContext.getBean("id1");
obj1.setValue(10);
System.out.println("The value for object obj1 is :" + obj1.getValue());
Sample obj2 = (Sample)appContext.getBean("id1");
System.out.println("The value for object obj2 is :" + obj2.getValue());
if(obj1 == obj2)
{
System.out.println("Both obj1 and obj2 are pointing to the same object.");
}
else
{
System.out.println("obj1 and obj2 are different objects.");
}
System.out.println("The address of object obj1 is :" + obj1);
System.out.println("The address of object obj2 is :" + obj2);
}
}
Output:
The value for object obj1 is :10
The value for object obj2 is:10
Both obj1 and obj2 are pointing to the same object.
The address of object obj1 is:bean.Sample@564213rt
The address of object obj2 is :bean.Sample@564213rt
Explanation:
We can clearly see that since the scope property in the bean was set to “singleton”, only one instance of the bean has been instantiated and this is shared amongst all the requests made by the user.
Prototype Scope:
If the scope is prototype, the spring IOC container will generate a new object of that bean whenever a request for that bean is created. A request to the bean instance can be generated programmatically by using getBean() method or via XML for Dependency Injection of secondary form.
Example:
Again, we first create the bean in our example.
// JAVA CODE
package bean;
public class Sample{
public int value;
//A setter method to set the value
public void setValue(int data)
{
this.value = data;
}
//A getter method to get the value
public String getValue()
{
return value;
}
}
Then we write the configuration file “SampleXML.xml” and configure the bean that we just created.
<!-- XML CODE -->
<!DOCTYPE beans PUBLIC
"-//SPRING//DTD BEAN 2.0//EN"
"http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
< bean
id = "id1"
class= "bean.Sample"
scope = "prototype" / >
</beans>
Then we write a driver class “User.java” which can request the above bean..
// JAVA CODE
package driver;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import bean.Sample;
public class User {
public static void main(String[] args)
{
// Loading the XML configuration file
ApplicationContext appContext = new ClassPathXmlApplicationContext( "resources/SampleXML.xml");
Sample obj1 = (Sample)appContext.getBean("id1");
obj1.setValue(10);
System.out.println("The value for object obj1 is :" + obj1.getValue());
Sample obj2 = (Sample)appContext.getBean("id1");
System.out.println("The value for object obj2 is :" + obj2.getValue());
if(obj1 == obj2)
{
System.out.println("Both obj1 and obj2 are pointing to the same object.");
}
else
{
System.out.println("obj1 and obj2 are different objects.");
}
System.out.println("The address of object obj1 is :" + obj1);
System.out.println("The address of object obj2 is :" + obj2);
}
}
Output:
The value for object obj1 is: 10
The value for object obj2 is: null
obj1 and obj2 are different objects.
The address of object obj1 is: bean.Sample@564213rt
The address of object obj2 is: bean.Sample@4361ae3w
Explanation:
We can clearly see that since the scope property in the bean was set to “prototype”, a new instance of the bean has been instantiated whenever a new request is made by the user.
You may know more about this framework and go through some important spring interview questions here: link
Q1. Briefly explain the three ways of implementing the lifecycle of a bean.
Ans. The three ways of implementing the lifecycle of a bean are:
Q2. What are inner beans in spring?
Ans. Only when a bean is used as a property of some other bean can it be deemed as an inner bean. Spring's XML-based configuration metadata allows you to define a bean by using the bean> element inside the property> or constructor-arg> elements. Inner beans are always anonymous, and their scope is always prototype.
Q3. What are stateful and stateless beans?
Ans. Stateless beans are singleton beans that are initialised only once. They possess a shared state.
Beans that can carry state are known as stateful beans (instance variables). Any time an object is needed, these beans are generated.
Q4. List the differences between singleton scope and prototype scope.
Singleton:
Prototype:
Q5. What is bean wiring?
Ans. Bean wiring is the process of combining beans inside a Spring container. When wiring beans, the Spring container needs to learn what beans are required and how the container can use dependency injection to connect the beans.
Q6. What are BeanPostProcessor beans?
Ans. BPP bean is a unique type of bean that is generated before any other bean and interacts with the newly created ones.
Q7. What is the work of a Spring bean configuration file?
Ans. All of the beans that will be initialised by Spring Context are defined by the Spring bean configuration file. When a Spring ApplicationContext object is generated, it reads the spring bean xml file and initializes all of the beans. If the context has been initialized, it can be used to obtain various bean instances.
Q8. Discuss auto-wiring and its different modes.
Ans. Spring includes a feature that allows you to automatically detect the relationships between different beans. All of the bean dependencies can be declared in the Spring configuration file. As a result, Spring will use the BeanFactory to determine the dependencies among all of the beans in use. The Spring container will automatically wire relationships between cooperating beans. That is, by inspecting the contents of the BeanFactory, you can have Spring automatically resolve collaborators for your bean.
Different modes of autowiring are:
Q9. What are the drawbacks of autowiring?
Ans. Following are the drawbacks of autowiring:
Q10. Why is spring bean with default scope not thread safe?
Ans. Spring bean's default scope is singleton, which means there will only be one instance per context. Inconsistent data would result from having a bean class level variable that every thread can update. As a result, spring beans are not thread-safe in default mode.
Q11. What are the different ways to configure a Java class as a spring bean?
Ans. There are three ways to set up a class as a Spring Bean:
The most common configuration is XML Configuration. The bean element tag is used to configure a Spring Bean in an xml context file.
The @Bean annotation can be used to configure a Spring bean using Java Based Configuration. This annotation is used to initialize a spring bean with @Configuration groups.
@Component, @Service, @Repository, and @Controller annotations with classes allow Annotation Based Configuration to configure them as spring beans. To search for these classes, we'd need to have a base package location.
Q12. If an inner bean defines an id, can we access it from a spring container using that id?
Ans. No, an inner bean cannot be fetched from a spring container even if the id attribute is defined. getBean("theInnerId") fails with NoSuchBeanDefinitionException.
Q13. Discuss Spring bean inheritance.
Ans. By determining parent and child beans, a spring bean may show inheritance actions. The abstract attribute value of true is used to configure the parent beans. The parent attribute on the bean tag, with the parent bean id as its value, can be used to configure a child bean.
A parent definition's configuration data is passed down to a child bean definition. The child concept has the ability to override a few values and add more as required.
While Spring Bean definition inheritance is not the same as Java class inheritance, the concepts are similar. You can use a parent bean specification as a reference, and other child beans can acquire the parent bean's required configuration.
Q14. Explain Bean Definition Template in Spring Framework.
Ans. Bean Definition Template, also known as parent beans, are used to describe common bean definitions that are shared by other child beans without having to rewrite them. When creating a Bean Definition Template, the class attribute should be left blank and the abstract attribute should be set to valid. Since it is incomplete and clearly labelled as abstract, the parent bean cannot be initialised on its own.
Q15. When is a singleton and a prototype bean garbage collected?
Ans. When the Spring container starts, singleton beans are made, and when the Spring container ceases, they are destroyed. The explanation for this is that the spring container retains a reference to it at all times, even if it is manually referenced elsewhere in your code.
Spring just takes care of the prototype bean's development and configuration; after that, it's up to the consumer (or the JVM) to do whatever is needed. Internal references to prototype beans are not kept by Spring.