18

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.

3 Answers 3

41

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:

Example of multiple singleton scoped bean

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

Sign up to request clarification or add additional context in comments.

1 Comment

@abd-elrahman-adel I rejected your edit because the /second prefix is specified in the second DispatcherServlet, so it should not be put inside the GetMapping annotation. All the code has been tested and it works as it is.
5

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.

Comments

1

The Singleton scope is scope in Spring. ApplicationScope is also singleton but it brings on the Java Enterprise, used for example in Java Server Faces (JSF)

2 Comments

i ask about the application scope in the spring framework ? spring has single scope and application scope then what is the difference between them ?
Oh my mistake. I thought ApplicationScoped for JEE. The difference of scoped you asked is the Context. Singleton scope is a singleton on Spring IoC container and AppplicaitonScope is also singleton but on web-aware ApplicationContext. You can see into the docs: docs.spring.io/spring/docs/current/spring-framework-reference/…. For example you can use ApplicaitonScope as a singleton in MVC.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.