Understanding Spring Bean Scope in Detail
Written on
Spring Bean Scope outlines how instances of objects are managed within a Spring application. It is essential to determine the lifespan and sharing mechanism of objects throughout your code.
The primary Spring Bean Scopes include:
Singleton:
Think of a favorite pen that you consistently use. In the Spring framework, a singleton bean functions similarly — there's only one instance created, and every time you need it, you access the same object.
The hash code can be utilized to confirm that the singleton bean instance remains consistent across the application.
Example:
@Component
@Scope("singleton")
public class SingletonBean {
private int count = 0;
public void incrementCount() {
count++;
}
public int getCount() {
return count;
}
public int getHashCode() {
return this.hashCode();
}
}
Next, we can modify the SingletonUser class to display the hash code:
@Component
public class SingletonUser {
@Autowired
private SingletonBean singletonBean;
public void useSingletonBean() {
singletonBean.incrementCount();
System.out.println("Singleton count: " + singletonBean.getCount() + ", Hash Code: " + singletonBean.getHashCode());
}
}
And here’s the MainApplication class:
@SpringBootApplication
public class MainApplication implements CommandLineRunner {
@Autowired
private SingletonUser singletonUser;
public static void main(String[] args) {
SpringApplication.run(MainApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
singletonUser.useSingletonBean();
singletonUser.useSingletonBean();
singletonUser.useSingletonBean();
}
}
Executing this application will yield an output similar to:
Singleton count: 1, Hash Code: 305078249
Singleton count: 2, Hash Code: 305078249
Singleton count: 3, Hash Code: 305078249
Explanation:
- Each invocation of useSingletonBean() prints the count and hash code of the SingletonBean.
- The hash code remains constant, indicating that the same instance is used throughout the application.
Prototype:
Visualize having a magical printer that produces a fresh copy of any object upon request. In Spring, a prototype-scoped bean behaves like that — each request generates a new instance.
Demonstrating how hash codes differ for each prototype bean instance:
@Component
@Scope("prototype")
public class PrototypeBean {
private static int instanceCount = 0;
private int id;
public PrototypeBean() {
instanceCount++;
this.id = instanceCount;
}
public int getId() {
return id;
}
public int getHashCode() {
return this.hashCode();
}
}
Updating the PrototypeUser class to output the hash code:
@Component
public class PrototypeUser {
@Autowired
private PrototypeBean prototypeBean;
public void usePrototypeBean() {
System.out.println("Prototype bean ID: " + prototypeBean.getId() + ", Hash Code: " + prototypeBean.getHashCode());
}
}
And the MainApplication class:
@SpringBootApplication
public class MainApplication implements CommandLineRunner {
@Autowired
private PrototypeUser prototypeUser;
public static void main(String[] args) {
SpringApplication.run(MainApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
prototypeUser.usePrototypeBean();
prototypeUser.usePrototypeBean();
prototypeUser.usePrototypeBean();
}
}
Running this application will produce:
Prototype bean ID: 1, Hash Code: 1324466193
Prototype bean ID: 2, Hash Code: 2125039533
Prototype bean ID: 3, Hash Code: 1265094472
Explanation:
- Each call to usePrototypeBean() generates a new PrototypeBean instance with a unique ID.
- The hash code varies for each instance, confirming that distinct objects are created for every request.
Request:
When a bean is defined with scope="request" or using @RequestScope, a new instance is created for every HTTP request made to your application.
Picture a web application where users log in. Each login request results in a new LoginAction bean instance, specific to that login attempt.
This LoginAction instance is limited to the login request, ensuring that operations performed are unique to that interaction.
Once the request is processed (login success or failure), Spring discards the LoginAction instance.
In summary:
- A new instance is generated for each HTTP request.
- Changes made during one request do not impact other requests.
- The bean is discarded upon completion of the request.
Example:
@RequestScope
@Component
public class LoginAction {
// ...
}
Session:
When a bean is defined with scope="session" or using @SessionScope, a single instance is created per user session.
Envision a web application where users can log in and set preferences. Each login results in a unique instance of UserPreferences for that user session.
This UserPreferences instance is exclusive to the user's session, allowing for personal customization without affecting others.
Once the session concludes (user logs out or times out), the instance is discarded.
Summary:
- One instance per user session.
- Changes during a session are isolated to that user.
- The bean is discarded at session end.
Example:
@SessionScope
@Component
public class UserPreferences {
// ...
}
Application Scope:
Imagine building a restaurant management system requiring shared global settings, such as opening hours or default preferences.
A class called AppPreferences would manage these settings. You can define this bean at the application level to ensure a single instance is utilized throughout the system.
Example:
@Component
@Scope("application")
public class AppPreferences {
// Properties and methods for global settings
}
Accessing the bean can be done anywhere in your application:
@Autowired
private AppPreferences appPreferences;
By changing the default language to French:
appPreferences.setDefaultLanguage("French");
This change will reflect across the application, ensuring uniformity.
WebSocket Scope:
WebSocket scope facilitates creating unique objects for each user's interaction with your application, akin to having a dedicated assistant for each visitor.
For instance, in a real-time chat application, tracking each user's chat history separately can be achieved through a WebSocket-scoped bean, such as ChatHistory.
Example:
@Component
@Scope(scopeName = "websocket", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class ChatHistory {
private List<String> messages = new ArrayList<>();
public void addMessage(String message) {
messages.add(message);
}
public List<String> getMessages() {
return messages;
}
}
In this case:
- ChatHistory is specific to each user.
- Messages are stored in the user's instance.
- Instances are cleared when the user disconnects.
In conclusion, understanding the various Spring bean scopes is crucial for effective management of object instances, ensuring that your application behaves as intended.
I hope this article has helped you grasp the concept of Spring bean scope. Please like and share it!
If you appreciated this content, consider showing your gratitude to the original author for their hard work.
Stay connected with us on JavaToDev’s LinkedIn for more updates and engaging discussions. Explore additional resources on the official JavaToDev website.
Thank you for your ongoing support, and here’s to continued growth in Java development!