ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Spring Bean Scopes
    Framework/SPRING 2019. 9. 29. 00:01

    1. Overview

    The scope of a bean defines the life cycle and visibility of that bean in the contexts in which it is used. The latest version of Spring framework defines 6 types of scopes

    • singleton
    • prototype
    • request
    • session
    • application
    • WebSocket
    • global session

    the previous version of bean types

    2. Description

    2.1 Singleton Scope

    The container creates a single instance of that bean, and all requests for that bean name will return the same object, which is cached. Any modifications for that bean will be reflected in all references to the bean. This scope is the default value if no other scope is specified.

    2.1.1 Example

    <!-- XML configuration of bean to test -->
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd">
     
        <bean id="personSingleton" class="org.baeldung.scopes.Person" scope="singleton"/>    
    </beans>
    // A Person entity to exemplify the concept of scopes
    public class Person {
        private String name;
     
        // standard constructor, getters and setters
    }
    
    // Define the bean with singleton scope by using the @Scope annotation:
    @Bean
    @Scope("singleton")
    public Person personSingleton() {
        return new Person();
    }
    
    @Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
    
    
    // also use a constant instead of the String value in the following manner:
    private static final String NAME = "John Smith";
     
     
    @Test
    public void givenSingletonScope_whenSetName_thenEqualNames() {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("scopes.xml");
     
        Person personSingletonA = (Person) applicationContext.getBean("personSingleton");
        Person personSingletonB = (Person) applicationContext.getBean("personSingleton");
     
        personSingletonA.setName(NAME);
        Assert.assertEquals(NAME, personSingletonB.getName());
     
     	// Will have the same values, even if only one of them changes their state, 
        // as they are both referencing the same bean instance:
        ((AbstractApplicationContext) applicationContext).close();
    }

    2.2 Prototype Scope

    Opposite to singleton, it produces a new instance each and every time a bean is requested. it is defined by setting the value prototype to the @Scope annotation in the bean definition

    2.2.1 Example

    <bean id="personPrototype" class="org.baeldung.scopes.Person" scope="prototype"/>
    @Bean
    @Scope("prototype")
    public Person personPrototype() {
        return new Person();
    }
    
    @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    private static final String NAME = "John Smith";
    private static final String NAME_OTHER = "Anna Jones";
     
    @Test
    public void givenPrototypeScope_whenSetNames_thenDifferentNames() {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("scopes.xml");
     
        Person personPrototypeA = (Person) applicationContext.getBean("personPrototype");
        Person personPrototypeB = (Person) applicationContext.getBean("personPrototype");
     
        personPrototypeA.setName(NAME);
        personPrototypeB.setName(NAME_OTHER);
     
        Assert.assertEquals(NAME, personPrototypeA.getName());
        Assert.assertEquals(NAME_OTHER, personPrototypeB.getName());
     
        ((AbstractApplicationContext) applicationContext).close();

    3. Web Aware Scopes

    3.1 Request Scope

    A single instance will be created and available during the complete lifecycle of an HTTP request. Only valid in web-aware Spring ApplicationContext.

    // The proxyMode attribute is necessary because, at the moment of the instantiation 
    // of the web application context, there is no active request. 
    // Spring will create a proxy to be injected as a dependency, 
    // and instantiate the target bean when it is needed in a request.
    @Bean
    @Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
    public HelloMessageGenerator requestScopedBean() {
        return new HelloMessageGenerator();
    }
    
    
    // In controller, an injected reference to the requestScopedBean is created. 
    // We need to access the same request twice in order to test the web specific scopes.
    
    // If we display the message each time the request is run, 
    // we can see that the value is reset to null, 
    // even though it is later changed in the method. 
    // This is because of a different bean instance being returned for each request.
    @Controller
    public class ScopesController {
        @Resource(name = "requestScopedBean")
        HelloMessageGenerator requestScopedBean;
     
        @RequestMapping("/scopes/request")
        public String getRequestScopeMessage(final Model model) {
            model.addAttribute("previousMessage", requestScopedBean.getMessage());
            requestScopedBean.setMessage("Good morning!");
            model.addAttribute("currentMessage", requestScopedBean.getMessage());
            return "scopesExample";
        }
    }

    3.2 Session Scope

    A single instance will be created and available during the complete lifecycle of an HTTP Session. Only valid in web-aware Spring ApplicationContext.

    @Bean
    @Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)
    public HelloMessageGenerator sessionScopedBean() {
        return new HelloMessageGenerator();
    }
    
    
    // In this case, when the request is made for the first time, the value message is null. 
    // But once, it is changed, then that value is retained for subsequent requests as 
    // the same instance of the bean is returned for the entire session.
    @Controller
    public class ScopesController {
        @Resource(name = "sessionScopedBean")
        HelloMessageGenerator sessionScopedBean;
     
        @RequestMapping("/scopes/session")
        public String getSessionScopeMessage(final Model model) {
            model.addAttribute("previousMessage", sessionScopedBean.getMessage());
            sessionScopedBean.setMessage("Good afternoon!");
            model.addAttribute("currentMessage", sessionScopedBean.getMessage());
            return "scopesExample";
        }
    }

    3.3 Application Scope

    A single instance will be created and available during the complete lifecycle of ServletContextOnly valid in web-aware Spring ApplicationContext.

    This is similar to the singleton scope but there is a very important difference with regards to the scope of the bean.

    When beans are application scoped the same instance of the bean is shared across multiple servlet-based applications running in the same ServletContext, while singleton-scoped beans are scoped to a single application context only.

    @Bean
    @Scope(value = WebApplicationContext.SCOPE_APPLICATION, proxyMode = ScopedProxyMode.TARGET_CLASS)
    public HelloMessageGenerator applicationScopedBean() {
        return new HelloMessageGenerator();
    }
    
    
    // in this case, value message once set in the applicationScopedBean will be retained 
    // for all subsequent requests, sessions and even for a different servlet application 
    // that will access this bean, provided it is running in the same ServletContext.
    @Controller
    public class ScopesController {
        @Resource(name = "applicationScopedBean")
        HelloMessageGenerator applicationScopedBean;
     
        @RequestMapping("/scopes/application")
        public String getApplicationScopeMessage(final Model model) {
            model.addAttribute("previousMessage", applicationScopedBean.getMessage());
            applicationScopedBean.setMessage("Good afternoon!");
            model.addAttribute("currentMessage", applicationScopedBean.getMessage());
            return "scopesExample";
        }
    }

    3.4 WebSocket Scope

    A single instance will be created and available during the complete lifecycle of WebSocketOnly valid in web-aware Spring ApplicationContext.

    WebSocket-scoped beans when first accessed are stored in the WebSocket session attributes. The same instance of the bean is then returned whenever that bean is accessed during the entire WebSocket session.

    We can also say that it exhibits singleton behavior but limited to a WebSocket session only.

    @Bean
    @Scope(scopeName = "websocket", proxyMode = ScopedProxyMode.TARGET_CLASS)
    public HelloMessageGenerator websocketScopedBean() {
        return new HelloMessageGenerator();
    }

    4. init method and destroy method

    <bean id="myCoach"
     		class="com.luv2code.springdemo.TrackCoach"
     		scope="singleton" init-method="init" destroy-method="destroy">

    4.1 Destroy method is not called for beans of scope prototype

    5. References

    https://www.java2novice.com/spring/bean-scope-types/

    https://stackoverflow.com/questions/17599216/spring-bean-scopes

    https://www.baeldung.com/spring-bean-scopes

    https://docs.spring.io/spring/docs/3.0.0.M3/reference/html/ch04s04.html

    https://howtodoinjava.com/spring-core/spring-bean-scopes/#targetText=The%20core%20of%20spring%20framework,are%20called%20spring%20bean%20scopes.

    https://stackoverflow.com/questions/16783552/destroy-method-is-not-working-in-spring-framework

    'Framework > SPRING' 카테고리의 다른 글

    Spring Framework  (0) 2020.02.06
    Spring MVC and Request Life Cycle  (0) 2020.02.03
    DispatcherServlet in Spring  (0) 2019.09.28
    Spring Security  (0) 2019.09.20
    Transaction Management  (0) 2019.09.17

    댓글

Designed by Tistory.