How do you create prototype-scoped beans in Spring?

Table of Contents

Introduction

In Spring, bean scopes define the lifecycle and visibility of beans within the Spring ApplicationContext. By default, Spring beans are singleton-scoped, meaning only one instance of a bean is created and shared across the entire application context. However, there are scenarios where you might want a new instance of a bean to be created every time it is requested. This is where the prototype scope comes into play.

In a prototype scope, a new instance of the bean is created every time it is requested from the Spring context, unlike the singleton scope where a single instance is shared. This makes prototype-scoped beans useful for situations where the bean's state should not be shared between different parts of the application.

In this guide, we will explore how to create and use prototype-scoped beans in Spring.

1. Understanding the Prototype Scope

The prototype scope means that the Spring container will create a new bean instance each time it is requested. Unlike singleton beans, which are created once and reused, prototype beans are created and discarded as soon as they go out of scope, without being managed after that.

The main characteristic of prototype-scoped beans is that Spring will not manage their complete lifecycle beyond creation. Once a prototype bean is created, it is not tracked or destroyed by the container. It is the responsibility of the developer or application to manage the lifecycle after the bean is created.

2. Defining a Prototype-Scoped Bean

To create a prototype-scoped bean, you can use the @Scope annotation with the value set to "prototype". This annotation can be applied to beans defined with the @Component, @Service, @Repository, or @Configuration annotations.

Example: Defining a Prototype-Scoped Bean

In this example:

  • The @Scope("prototype") annotation ensures that every time the PrototypeBean is requested from the Spring context, a new instance will be created.
  • The System.out.println("PrototypeBean instance created!") statement in the constructor will show that a new bean is created every time it is requested.

3. Accessing Prototype-Scoped Beans

To use a prototype-scoped bean, you simply request it from the Spring ApplicationContext as you would with any other bean. However, since prototype beans are not managed like singleton beans, you will need to manually fetch them every time you need a new instance.

Example: Accessing Prototype Beans in a Singleton

Spring does not automatically inject a new instance of prototype-scoped beans into singleton beans, even though the prototype-scoped beans are defined in the application context. You will have to explicitly request the prototype bean from the context.

In this example:

  • The SingletonBean is a singleton-scoped bean.
  • The PrototypeBean is injected manually via the ApplicationContext using context.getBean(PrototypeBean.class).
  • Each time doSomethingWithPrototype() is called, a new instance of PrototypeBean is retrieved.

4. Prototype Beans in Constructor or Setter Injection

If you need to inject a prototype bean directly into another bean, the same principle applies. Spring will not inject a new prototype bean by default into a singleton bean; however, you can make use of a @Lookup annotation or access the prototype bean via the ApplicationContext.

Example: Using @Lookup Annotation for Prototype Injection

Spring provides the @Lookup annotation to inject a new prototype bean each time a method is called in a singleton bean. When the @Lookup annotation is used, Spring will override the method and inject a new instance of the prototype-scoped bean.

In this example:

  • The getPrototypeBean() method is annotated with @Lookup.
  • Spring will inject a new instance of the prototype bean each time the method is called.

5. How Prototype Beans are Destroyed

Unlike singleton beans, which are destroyed by Spring when the application context is closed, prototype beans do not have any lifecycle management beyond creation. This means that if the prototype bean implements DisposableBean or if it has a custom destroy method, Spring will not call the destroy method when the bean goes out of scope. You will need to manually manage the destruction of prototype beans, typically by handling it yourself or using a @PreDestroy method.

6. Practical Example: Using Prototype Beans in a Spring Boot Application

Define a Prototype Bean

Access Prototype Bean from the ApplicationContext

In this example:

  • Each time context.getBean(PrototypeService.class) is called, a new instance of PrototypeService will be created and injected into MainService.

Conclusion

In Spring, prototype-scoped beans are useful when you need a new instance of a bean each time it is requested. These beans are created and initialized every time they are requested from the Spring container. The @Scope("prototype") annotation allows you to define such beans, and it can be combined with other annotations like @Lookup to inject them into singleton beans. Managing the lifecycle of prototype beans requires careful attention, as Spring will not handle their destruction automatically.

Prototype beans are ideal for situations where a bean's state should not be shared across different parts of the application, making them an essential tool in the Spring framework.

Similar Questions