Prototype Bean Spring Dependency Injection

It is a common and widely used practice to call ApplicationContext.getBean(class), to get a new instance of a Prototype scoped bean. While it is a convenient method, there are some issues in this approach.

A class should be aware of only those other classes which it depends on for delivering functionality expected from it. When we choose to make dependency available to a Class through a call to ApplicationContext.getBean(), we bring following problems in the codebase:

  1. The class gets access to the entire Spring beans collection and plethora of Spring container functionality, which that class doesn’t need and most likely isn’t aware of.
  2. This reduces code maintainability and readability, as the Constructor is no more a place to find dependencies.

I wish to make you familiar with an another approach of getting new instances of Prototype Scoped bean.

Suppose there is a class called ‘Worker’ which is a Prototype scoped component.

package com.example.demo;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Scope("prototype")
@Component
public class Worker {

public void handleWork(WorkRequest workRequest) {
System.out.println("Work has been started");
}
}

To create a new instance of Worker class through Spring annotations, you can @autowire ObjectFactory of Worker class, Spring framework injects an instance of ObjectFactory that provides a new Worker object every time:

package com.example.demo;

import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class WorkManager {

private final ObjectFactory<Worker> workerObjectFactory;

@Autowired
public WorkManager(ObjectFactory<Worker> workerObjectFactory) {
this.workerObjectFactory = workerObjectFactory;
}

public void acceptWork(WorkRequest workRequest) {
final Worker worker = workerObjectFactory.getObject();
worker.handleWork(workRequest);
}
}

workerObjectFactory.getObject() will always return a new object.

This method has following benefits over the traditional approach:

  1. Inversion of control
  2. Component dependencies are clearly visible through Constructor

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.