How do you implement prototype-scoped beans in Spring?
Table of Contents
- Introduction
- Implementing Prototype-Scoped Beans in Spring
- How Spring Manages Prototype Beans
- Practical Considerations When Using Prototype Beans
- Conclusion
Introduction
In Spring Framework, the scope of a bean determines how and when the bean is created, and how long it will live within the Spring container. By default, Spring beans are singleton-scoped, meaning only one instance of the bean is created and shared across the application. However, there are cases where you may need a new instance of a bean to be created each time it is requested. This can be achieved by using the @Scope("prototype")
annotation, which makes the bean prototype-scoped. In this guide, we will explore how to implement prototype-scoped beans in Spring, along with practical examples.
Implementing Prototype-Scoped Beans in Spring
1. Using @Scope("prototype")
Annotation
To define a prototype-scoped bean in Spring, you simply need to annotate the class or method that defines the bean with @Scope("prototype")
. This will instruct the Spring container to create a new instance of the bean every time it is requested.
Example 1: Defining a Prototype Bean Using @Component
You can define a prototype-scoped bean using the @Component
annotation and specifying the @Scope("prototype")
annotation.
In this example, every time PrototypeBean
is requested from the Spring container, a new instance will be created with the provided message.
2. Using @Scope("prototype")
with @Bean
in Java Config
If you are using Java-based configuration, you can define a prototype-scoped bean using the @Bean
annotation along with @Scope("prototype")
.
Example 2: Defining a Prototype Bean in Java Config
Here, prototypeBean()
defines a prototype-scoped bean, meaning that a new instance will be created each time it is requested from the Spring context.
How Spring Manages Prototype Beans
In a prototype-scoped bean, Spring does not manage the lifecycle of the bean beyond its creation. This means that while the container creates a new instance every time, the container does not handle the destruction of the bean. For any necessary cleanup or destruction, you would need to manage that manually using methods like @PreDestroy
or other lifecycle hooks.
3. Example: Requesting Multiple Instances of a Prototype Bean
To understand how prototype-scoped beans work, let's look at an example where we request the same prototype-scoped bean multiple times and verify that different instances are created.
In this example, bean1
and bean2
will be different instances because PrototypeBean
is a prototype-scoped bean. Spring creates a new instance every time you request it.
Practical Considerations When Using Prototype Beans
1. Injecting Prototype Beans into Singleton Beans
Since prototype-scoped beans are instantiated on-demand, injecting them into singleton-scoped beans (which are created once and shared) requires special handling. If you inject a prototype bean directly into a singleton, Spring will inject the same instance of the prototype bean each time, which can be problematic. You can solve this by using @Autowired
with ObjectFactory
or Provider
to obtain a new instance each time.
Example 3: Injecting Prototype Bean into Singleton
In this case, ObjectFactory<PrototypeBean>
allows Spring to create a new instance of PrototypeBean
every time the getObject()
method is called, even though the SingletonBean
is a singleton.
2. Cleaning Up Prototype Beans
Since Spring does not manage the destruction of prototype beans, you may need to manually handle cleanup tasks, such as closing resources, when the prototype bean is no longer in use. You can use the @PreDestroy
annotation or a custom destroy method to perform cleanup tasks.
In this example, the destroy()
method will be called when the bean is destroyed, which can be useful for cleanup tasks.
Conclusion
Prototype-scoped beans in Spring allow you to create a new instance of a bean each time it is requested, making them ideal for cases where each request requires a distinct object, such as for stateless services or temporary resources. To implement prototype-scoped beans, you can use the @Scope("prototype")
annotation on your bean classes or @Bean
methods. However, it is important to be aware of the lifecycle management considerations, particularly when injecting prototype beans into singleton beans. By understanding and properly managing prototype-scoped beans, you can ensure your application remains flexible and efficient in terms of object creation and resource management.