What is the difference between the singleton and application spring scopes ?
I know that the singleton scope creates one instance per application and the application scope is working in the same way, then what is the main difference ?
I need an example to shows me the difference.
Singleton: means single bean definition to a single object instance per Spring IOC container. Prototype: means a single bean definition to any number of object instances.
The Spring Framework supports the following five scopes, three of which are available only if you use a web-aware ApplicationContext. Sr.No. This scopes the bean definition to a single instance per Spring IoC container (default). This scopes a single bean definition to have any number of object instances.
The scope of the Spring singleton is best described as per container and per bean. This means that if you define one bean for a particular class in a single Spring container, then the Spring container will create one and only one instance of the class defined by that bean definition.
In the application scope, Spring creates a bean instance per web application runtime. It is similar to singleton scope, with one major difference. Singleton scoped bean is singleton per ApplicationContext where application scoped bean is singleton per ServletContext.
To understand the difference between application scope and singleton scope you need to understand what ServletContext and ApplicationContext are.
A ServletContext
is shared between all servlets living on the same servlet container (e.g. Tomcat). This is a Java EE class (it belongs to the package javax.servlet
). Beans annotated with @ApplicationScope
are bounded to the ServletContext.
An ApplicationContext
represents a Spring IoC container, so it is a Spring-specific class (it belongs to the package org.springframework.context
). Singleton scoped beans are bounded to the ApplicationContext.
You can have multiple IoC container in the same servlet container, so you can have multiple singleton beans of the same type but only one application scoped bean of each type.
I provide an example using Spring Boot and Spring MVC.
We need to introduce also the DispatcherServlet
. The DispatcherServlet receives HTTP requests and forwards them to the appropriate controller. An ApplicationContext is associated to each DispatcherServlet. It is possible to configure Spring to create multiple DispatcherServlets and associate a different ApplicationContext to each of them.
Notice that in a standard configuration there is only one DispatcherServlet, so it is usually not possible to distinguish a singleton scoped bean from an application scoped bean. I would also like to point out that I see no practical use for the custom configuration I'm going to show you, other than to provide a concrete example of the difference between these two scopes.
The following diagram shows the relations between all the elements of the example:
Let's look at the code. Please, pay attention to the package names!
In the package com.example.demo.beans
we create the 2 beans. A random number is generated during beans initialization, so that we can distinguish them.
@ApplicationScope
@Component
public class MyApplicationScopeBean {
private final double id = Math.random();
public double getId() {
return id;
}
}
// Singleton is the default scope
@Component
public class MySingletonBean {
private final double id = Math.random();
public double getId() {
return id;
}
}
The startup class is put in com.example.demo
:
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
// The first ApplicationContext is instantiated here
// (it is also returned by the method).
SpringApplication.run(DemoApplication.class, args);
}
/**
* A new DispatcherServlet is instantiated and registered.
*/
@Bean
public ServletRegistrationBean mvc2() {
// A new ApplicationContext is created, using a dedicated Configuration class.
AnnotationConfigWebApplicationContext secondApplicationContext = new AnnotationConfigWebApplicationContext();
secondApplicationContext.register(Mvc2Config.class);
DispatcherServlet dispatcherServlet = new DispatcherServlet();
dispatcherServlet.setApplicationContext(secondApplicationContext);
DispatcherServletRegistrationBean servletRegistrationBean = new DispatcherServletRegistrationBean(dispatcherServlet, "/second/*");
servletRegistrationBean.setName("second");
return servletRegistrationBean;
}
}
In the same package we put also the controller that will be bounded to the default DispatcherServlet generated by Spring Boot:
@RestController
public class FirstController {
@Autowired
private MyApplicationScopeBean applicationScopeBean;
@Autowired
private MySingletonBean singletonBean;
@GetMapping("/first/demo")
public String output() {
return "applicationScope=" + applicationScopeBean.getId() + ", singleton=" + singletonBean.getId();
}
}
In the package com.example.demo.mvc2
we put the second configuration class:
@Configuration
@ComponentScan(basePackages = {"com.example.demo.mvc2", "com.example.demo.beans"})
@EnableWebMvc
public class Mvc2Config {
}
And the controller bounded to the second DispatcherServlet:
@RestController
public class SecondController {
@Autowired
private MyApplicationScopeBean applicationScopeBean;
@Autowired
private MySingletonBean singletonBean;
@GetMapping("/demo")
public String output() {
return "applicationScope=" + applicationScopeBean.getId() + ", singleton=" + singletonBean.getId();
}
}
If you run the code you can see that the id of the application scoped bean is the same in both the controllers, while the id of the singleton beans changes:
http://localhost:8080/first/demo
applicationScope=0.8685117272969953, singleton=0.23475401462261436
http://localhost:8080/second/demo
applicationScope=0.8685117272969953, singleton=0.8390865330171554
https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-factory-scopes-application
This is somewhat similar to a Spring singleton bean but differs in two important ways: It is a singleton per ServletContext, not per Spring 'ApplicationContext' (for which there may be several in any given web application), and it is actually exposed and therefore visible as a ServletContext attribute.
i.e. web application may have several Spring application contexts and therefore several instances of bean with singleton scope (one instance per spring app contexts) but only one bean defined with application scope.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With