How do you create prototype-scoped beans in Spring?
Table of Contents
- Introduction
- Conclusion
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 thePrototypeBean
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 theApplicationContext
usingcontext.getBean(PrototypeBean.class)
. - Each time
doSomethingWithPrototype()
is called, a new instance ofPrototypeBean
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 ofPrototypeService
will be created and injected intoMainService
.
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.