Injecting Prototype bean into a Singleton bean in Spring

In this post, we will see how to inject prototype bean scope into Singleton Instance in Spring. This is one of the most asked Spring interview questions.

Problem

When you inject prototype bean to singleton bean, prototype bean still behave like a singleton bean.

Let’s understand this with the help of example.
1. Create a simple java maven project.
2. Maven dependency
put spring and cglib maven dependency in pom.xml.

So your pom.xml will look like:

3. Create Bean class

Create a bean class called X.java in package org.arpit.java2blog .
Create another bean class called Y.java in package org.arpit.java2blog.

4. ApplicationContext.xml
Create ApplicationContext.xml in src/main/resources as below.

We have just declared two bean x and y here.
5. Create InjectPrototypeToSingletonMain.java

6. Run it
When you run above program, you will get below output.

Jun 15, 2018 1:32:58 PM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@31cefde0: startup date [Fri Jun 15 13:32:58 IST 2018]; root of context hierarchy
Jun 15, 2018 1:32:58 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [ApplicationContext.xml] do two prototype bean point to same object: true
Jun 15, 2018 1:32:59 PM org.springframework.context.support.ClassPathXmlApplicationContext doClose
INFO: Closing org.springframework.context.support.ClassPathXmlApplicationContext@31cefde0: startup date [Fri Jun 15 13:32:58 IST 2018]; root of context hierarchy

As you can note here, even though we have declared bean Y as prototype, still it is behaving like a singleton bean only.

Solution

There are many ways to solve this problem.

Using Method injection

Update X.java as below.

You can use method injection to solve this problem.Simply use @Lookup with getY() method, it will return new instance each time.
Spring will use CGLIB to generate dynamically a subclass that overrides the method getY(). It then registers the bean into the application context. Whenever we request for getY() method, it will return new instance of Class Y.

There are two options here, either create dummy method or mark method as abstract. When you mark method as abstract, then you will have to declare class abstract as well, hence we have used dummy method in this scenario.

Run InjectPrototypeToSingletonMain again
You will get below output:

Jun 15, 2018 1:51:38 PM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@31cefde0: startup date [Fri Jun 15 13:51:38 IST 2018]; root of context hierarchy
Jun 15, 2018 1:51:38 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [ApplicationContext.xml] do two prototype beans of type Y point to same object: false
Jun 15, 2018 1:51:38 PM org.springframework.context.support.ClassPathXmlApplicationContext doClose
INFO: Closing org.springframework.context.support.ClassPathXmlApplicationContext@31cefde0: startup date [Fri Jun 15 13:51:38 IST 2018]; root of context hierarchy

As you can note now, we are getting two different instance of Y now.

Using ObjectFactory

You can use ObjectFactory to get new object each time getY() method is called.
Update class A.java as below

Run InjectPrototypeToSingletonMain again
You will get below output:

Jun 15, 2018 2:55:56 PM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@31cefde0: startup date [Fri Jun 15 14:55:56 IST 2018]; root of context hierarchy
Jun 15, 2018 2:55:57 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [ApplicationContext.xml] do two prototype beans of type Y point to same object: false
Jun 15, 2018 2:55:58 PM org.springframework.context.support.ClassPathXmlApplicationContext doClose
INFO: Closing org.springframework.context.support.ClassPathXmlApplicationContext@31cefde0: startup date [Fri Jun 15 14:55:56 IST 2018]; root of context hierarchy

Using ApplicationContextAware

You can return new bean using application context wheneven getY() method is getting called.
Update class A.java as below

Run InjectPrototypeToSingletonMain again
You will get below output:

Jun 15, 2018 2:58:59 PM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@31cefde0: startup date [Fri Jun 15 14:58:59 IST 2018]; root of context hierarchy
Jun 15, 2018 2:58:59 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [ApplicationContext.xml] do two prototype beans of type Y point to same object: false
Jun 15, 2018 2:59:00 PM org.springframework.context.support.ClassPathXmlApplicationContext doClose
INFO: Closing org.springframework.context.support.ClassPathXmlApplicationContext@31cefde0: startup date [Fri Jun 15 14:58:59 IST 2018]; root of context hierarchy

That’s all about Injecting Prototype bean into a Singleton bean in Spring.

For more questions, refer Spring interview questions.

Was this post helpful?

Leave a Reply

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