Spring: Injecting Prototype Bean into Singleton Bean

Spring context supports singleton and prototype bean scopes along with four other scopes specific to the web context. The singleton is the default bean scope.

A common problem arises when we want to inject a prototype-scoped bean into a singleton-scoped bean. In this case, as the singleton bean is initialized only once per application context, we need to apply extra logic to initialize the prototype-scoped bean so that it is created every time. This problem is known as the scoped bean injection problem.

1. Scoped Bean Injection Problem

This problem is mainly encountered when we have to inject the non-thread-safe bean instances into other beans. For example, classes like SimpleDateFormat and JAXBContext are not thread-safe.

If we are injecting these beans into another bean, then we need to make sure that a new instance of SimpleDateFormat or (JAXBContext) must be created everytime when the parent bean is requested in another thread.

@Component
public class XmlUtils {			//This must be singleton scoped
	
	@Autowired
	private JAXBContext jaxbContext;	//This must be prototype scoped
}

2. Using Lookup Method Injection

The easiest way to solve the scoped bean problem is using the lookup method injection using @Lookup annotation. Such lookup methods are overridden by the container to redirect them back to the BeanFactory for a getBean() call via CGLIB.

This is essentially an annotation-based version of the XML ‘lookup-method’ attribute.

@Component
public class XmlUtils {

  @Lookup
  public JAXBContext getJAXBContext() {
      return null;
  }
}

3. Using ApplicationContext

If we already have access to ApplicationContext in the singleton bean, we can use it to obtain the prototype-scoped bean instance whenever we need it. Usually, a new instance is obtained using the getter method.

@Component
public class XmlUtils implements ApplicationContextAware {
	
	private ApplicationContext applicationContext;

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
	    this.applicationContext = applicationContext;
	}

    public JAXBContext getJAXBContext() {
        return applicationContext.getBean(JAXBContext.class);
    }
}

Note that we are creating a new instance everytime the getter is invoked, so if not used cautiously, we may be creating more than necessary instances in the application. Also, if the object is costly to create then each unnecessary object creation is overhead.

Another issue is that we are not following the conventional dependency injection practice, so it is hard to keep track of such changes when we have to maintain the application over years.

4. Using ObjectFactory or Provider Interfaces

The Spring’s ObjectFactory interface is used to encapsulate a generic factory that returns a new instance (prototype) of some target object on each invocation.

@Component
public class XmlUtils {
	
  @Autowired
  private ObjectFactory<JAXBContext> jaxbContextObjectFactory;

  public JAXBContext getJAXBContext() {
      return jaxbContextObjectFactory.getObject();
  }
}

The Provider interface is also very similar to ObjectFactory. It injects a new instance of prototype bean everytime its get() method is invoked.

@Component
public class XmlUtils {
	
  @Autowired
  private Provider<JAXBContext> jaxbContextProvider;

  public JAXBContext getJAXBContext() {
      return jaxbContextProvider.get();
  }
}

5. Conclusion

In this Spring tutorial, we learned to inject the prototype scoped beans into singleton scoped beans. We learned to solve the scoped bean injection problem using the lookup method injection, ApplicationContext injection, and ObjectFactory and Provider interfaces to inject new instances for each invocation to the beans getter method.

Happy Learning !!

Comments

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.

Our Blogs

REST API Tutorial

Dark Mode

Dark Mode