Prototype-scoped Bean Instance in Spring
Spring Framework supports quite a few different types of bean scopes. Singleton and Prototype scoped beans are the most used ones. It is common for Spring framework-based applications to use singleton scoped beans, but sometimes, there may be a need to use a prototype scoped bean. In this post, I will show how to get an instance of a prototype-scoped bean in Spring Framework.
This can be done using by using Method injection. In the annotation-based configuration, there are two choices based on the version of the Spring framework is used. Suppose using the Spring version older than 4.1.x, then javax.inject.Providerinterface needs to be used to create a provider to get the instance of the prototype bean. Since Spring 4.1.x, a new annotation introduced - @lookup - is an annotation-based alternative to method injection. Following is an example of creating a factory class for QueueTask class using both methods:
@Component
@Scope("prototype")
public class QueueTask {
@Autowired
private AtomicInteger dataIdCounter;
@Autowired
private IntegrationTasksRepository integrationTasks;
@Autowired
private MongoOperations mongoOps;
@Autowired
private SquadRunItemsRepository squadRunItems;
@Autowired
private AmazonS3Service amazonS3Service;
@Override
public void run() {
// Do stuff
}
}
// Use this if you use Spring version >= 4.1.x @Component
public class IntegrationTaskFactory {
@Lookup //use of lookup annotation
public QueueTask getQueueTask(){
//spring will override this method
return null;
}
public QueueTask getQueueTaskWithParams(Map<String, String> params) {
// Get a new QueueTask object
QueueTask task = getQueueTask();
// Customize task based on params ...
// Return the object
return task;
}
}
// Use this if you use Spring version < 4.1.x @Component
public class IntegrationTaskFactory {
@Autowired
private Provider<QueueTask> myQueueTask;
// Use of javax.inject.Provider interface
public QueueTask getQueueTaskWithParams(Map<String, String> params) {
// Get a new QueueTask object
QueueTask task = myQueueTask.get();
// Customize task based on params ...
// Return the object
return task;
}
}
Method injection can be done in XML-based configuration similarly as shown in the documentation.
Update: The original motivation for writing this post is that while there is a section on Method injection in Spring documentation, the use of @lookup annotation is not shown. Since writing this post, I created a documentation issue in Spring Jira. To my surprise, the issue is resolved, and documentation is updated within five days by Spring Framework lead Juergen Hoeller. You can check the current document, showing the use of @lookup annotation, here.