Spring Framework supports quite a few different types of bean scopes. Singleton and Prototye scoped beans are the mostly used ones. It is common for Spring framework based applications to use singleton scoped beans, but sometime there may be a need to use a prototype scoped bean. In this post, I will show how to get instance of a prototype-scoped bean in Spring Framework.

This can be done using by using Method injection. In annotation based configuration, there are two choices based upon the version of Spring framework is used. If using Spring version older than 4.1.x, then javax.inject.Providerinterface need to be used to create a provider to get the instance of the prototype bean. Since Spring 4.1.x, there is a new annotation introduced @lookup which is basically annotation based alternative of 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 in a similar way as shown in the documentation.

Update: The original motivation of 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. And to my surprise, the issue is resolved and documentation is updated within 5 days by Spring Framework lead Juergen Hoeller. You can check the current document, showing the use of @lookup annotation, here.