본문 바로가기

개발/Spring

[Spring Framework] Bean Scopes

빈의 생명 주기를 관리하기 위한 개념.

빈이 생성되고 소멸되는 시점과 그 유효성을 정의합니다.

빈의 스코프를 적절히 선택하는 것은 애플리케이션의 성능과 효율적인 자원 관리를 위해 사용됩니다.

 

Singleton (싱글톤)

Spring 컨테이너 내에서 단 하나의 인스턴스만 생성됩니다. 가장 기본적이고 널리 사용되는 범위입니다.

자원 측면에서 효율적이지만, 상태를 가질 경우 동시성 문제가 발생할 수 있습니다.

@Component
@Scope("singleton")
public class MyBean {
    // ...
}

 

Practice

ApplicationContext에서 빈을 2번 가져왔을 때, 둘이 같은지 확인한다.

public abstract class ScopeConst {

    public final static String SINGLETON = "singleton";
    public final static String PROTOTYPE = "prototype";
}
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Scope;

import static com.xiyoon.springscope.ScopeConst.SINGLETON;

public class SingletonTest {

    @Test
    public void findSingletonBean() {
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(SingletonBean.class);
        SingletonBean bean1 = ac.getBean(SingletonBean.class);
        SingletonBean bean2 = ac.getBean(SingletonBean.class);
        Assertions.assertEquals(bean1, bean2);
        ac.close();
    }

    @Scope(SINGLETON)
    static class SingletonBean {
        @PostConstruct
        public void init() {
            System.out.println("SingletonBean init");
        }

        @PreDestroy
        public void destroy() {
            System.out.println("SingletonBean destroy");
        }
    }
}

테스트 성공 (두 빈이 동일하다) + 빈을 두 번 받았지만 초기화가 한번만 일어난다. 또한 컨텍스트를 닫을 때, 종료가 한번만 일어난다. 즉, 하나의 빈만 존재한다.

Prototype (프로토타입)

요청할 때마다 새로운 빈 인스턴스를 생성합니다.

Spring 컨테이너는 빈의 초기화까지만 관리하며, 소멸에 대한 관리는 하지 않습니다.

각 요청마다 새로운 인스턴스가 필요할 때 유용합니다.

 

Practice

ApplicationContext에서 빈을 2번 가져왔을 때, 둘이 다른지 확인한다.

public abstract class ScopeConst {

    public final static String SINGLETON = "singleton";
    public final static String PROTOTYPE = "prototype";
}
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Scope;

import static com.xiyoon.springscope.ScopeConst.PROTOTYPE;

public class PrototypeTest {

    @Test
    void findPrototypeBean() {
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(PrototypeBean.class);
        PrototypeBean prototypeBean1 = ac.getBean(PrototypeBean.class);
        PrototypeBean prototypeBean2 = ac.getBean(PrototypeBean.class);
        Assertions.assertNotEquals(prototypeBean1, prototypeBean2);
        ac.close();
    }

    @Scope(PROTOTYPE)
    public static class PrototypeBean {

        @PostConstruct
        public void init() {
            System.out.println("PrototypeBean init");
        }

        @PreDestroy
        public void destroy() {
            System.out.println("PrototypeBean destroy");
        }
    }
}

테스트 성공 (두 빈이 다르다) + 빈을 두 번 받았고 초기화도 두 번 일어난다. 즉, 두 개의 빈이 존재한다. 또한 컨텍스트를 닫을 때, 종료가 일어나지 않는다. 즉, 클라이언트로 권한을 넘겼다.

Request (요청)

HTTP 요청 하나당 하나의 빈 인스턴스를 생성합니다. (동일한 HTTP 요청 내에서는 같은 빈 인스턴스가 사용됩니다.)

HTTP 요청이 끝나면 빈 인스턴스도 소멸됩니다.

Session (세션)

HTTP 세션 하나당 하나의 빈 인스턴스를 생성합니다. (사용자의 세션 동안에는 동일한 빈 인스턴스가 사용됩니다.)
세션이 만료되면 빈 인스턴스도 소멸됩니다.

Application (애플리케이션) 

ServletContext와 동일한 생명 주기를 가집니다.

애플리케이션 전체에서 하나의 인스턴스를 공유합니다.
웹 애플리케이션이 실행되는 동안 계속 존재합니다.

WebSocket (웹소켓)

웹소켓 연결 하나당 하나의 빈 인스턴스를 생성합니다. (웹소켓 연결 동안에는 동일한 빈 인스턴스가 사용됩니다.)

웹소켓 연결이 종료되면 빈 인스턴스도 소멸됩니다.

 

Reference
https://docs.spring.io/spring-framework/reference/core/beans/factory-scopes.html
728x90
반응형