[Day 25 | Spring] Bean Scope (접근 범위)

y♡ding·2024년 11월 15일
0

데브코스 TIL

목록 보기
157/163

Bean Scope는 스프링 컨테이너에서 빈 객체의 생명 주기와 접근 범위를 결정하는 설정입니다. 스프링에서는 다양한 범위(Scope)를 제공하여 빈을 관리할 수 있으며, 각 스코프는 빈이 생성되고 활용되는 방식을 다르게 정의합니다. 이를 통해 필요한 용도에 따라 빈의 범위를 설정하고, 자원을 효율적으로 사용할 수 있습니다.

1. Bean Scope의 종류

스프링에서 제공하는 주요 스코프는 다음과 같습니다:

1) Singleton (기본 스코프)

  • 설명: 하나의 스프링 컨테이너(Application Context) 내에서 단 하나의 인스턴스만 생성됩니다.
  • 사용 시점: 애플리케이션 전역에서 공유되는 빈이 필요할 때 사용합니다.
  • 장점: 자원을 절약할 수 있으며, 공통된 데이터를 사용할 때 적합합니다.
  • 설정 방법: 별도의 설정 없이 기본값으로 사용되며, @Scope("singleton")을 통해 명시적으로 지정할 수도 있습니다.
<bean id="singletonBean" class="com.example.MyBean" scope="singleton"/>

!https://docs.spring.io/spring-framework/reference/_images/singleton.png

2) Prototype

  • 설명: 빈을 요청할 때마다 새로운 인스턴스를 생성합니다.
  • 사용 시점: 상태가 있는 객체나 여러 인스턴스를 독립적으로 관리할 필요가 있을 때 사용합니다.
  • 주의점: 스프링 컨테이너는 프로토타입 빈의 생명 주기를 관리하지 않으므로, 빈이 소멸될 때 자원 정리가 필요하면 개발자가 직접 처리해야 합니다.
  • 설정 방법: @Scope("prototype") 또는 XML 설정에서 scope="prototype"으로 설정합니다.
<bean id="prototypeBean" class="com.example.MyBean" scope="prototype"/>

!https://docs.spring.io/spring-framework/reference/_images/prototype.png


💡

위 두가지 Scope이 가장 중요해요.

아래 Scope은 참고용으로 필요할 때만 사용하세요.

3) Request (웹 애플리케이션 전용)

  • 설명: 웹 요청 당 하나의 빈 인스턴스를 생성하여, 요청이 끝나면 소멸됩니다.
  • 사용 시점: HTTP 요청별로 상태를 유지하는 빈이 필요할 때 적합합니다.
  • 주의점: 웹 애플리케이션 컨텍스트에서만 사용 가능하며, 요청이 끝나면 자동으로 소멸됩니다.
  • 설정 방법: @Scope("request") 또는 XML 설정에서 scope="request"로 설정합니다.
<bean id="requestBean" class="com.example.MyBean" scope="request"/>

4) Session (웹 애플리케이션 전용)

  • 설명: 웹 세션 당 하나의 인스턴스를 생성하며, 세션이 종료될 때 소멸됩니다.
  • 사용 시점: 사용자 세션별로 독립적인 빈 인스턴스를 유지할 때 적합합니다.
  • 주의점: 웹 환경에서만 사용 가능하며, 세션이 끝날 때 빈이 소멸됩니다.
  • 설정 방법: @Scope("session") 또는 XML 설정에서 scope="session"으로 설정합니다.
<bean id="sessionBean" class="com.example.MyBean" scope="session"/>

5) Application (웹 애플리케이션 전용)

  • 설명: 서블릿 컨텍스트 범위 내에서 하나의 인스턴스를 생성하여 애플리케이션 전역에서 공유합니다.
  • 사용 시점: 애플리케이션 전체에서 동일한 객체를 사용해야 하는 경우에 적합합니다.
  • 설정 방법: @Scope("application") 또는 XML 설정에서 scope="application"으로 설정합니다.
<bean id="applicationBean" class="com.example.MyBean" scope="application"/>

6) WebSocket (웹 소켓 전용)

  • 설명: 웹 소켓 세션 범위 내에서 하나의 빈 인스턴스를 생성하여 사용합니다.
  • 사용 시점: 웹 소켓 세션별로 독립적인 빈이 필요할 때 사용합니다.
  • 주의점: 웹 소켓 지원 환경에서만 사용 가능합니다.
  • 설정 방법: @Scope("websocket")으로 설정합니다.

2. 스코프 설정 방법

  • 어노테이션 기반: @Scope 어노테이션을 사용하여 빈 스코프를 지정할 수 있습니다.
    @Component
    @Scope("prototype")
    public class MyBean { ... }
    
  • XML 설정 기반: <bean> 태그에 scope 속성을 사용하여 스코프를 지정합니다.
    <bean id="myBean" class="com.example.MyBean" scope="prototype"/>
    

3. Bean Scope 활용 시 주의 사항

  • 싱글톤 스코프 빈은 애플리케이션 전역에서 사용되는 데이터에 적합하나, 상태가 변하지 않도록 주의해야 합니다.
  • 프로토타입 빈은 요청마다 새 인스턴스를 생성하므로, 메모리 사용에 유의해야 합니다.
  • Request, Session, Application 스코프는 웹 환경에서만 사용할 수 있으며, 주로 웹 애플리케이션의 상태 유지를 위해 사용됩니다.

예제: Singleton과 Prototype 스코프 비교

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class ScopeExample {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");

        // Singleton 스코프: 동일한 인스턴스를 반환
        MyBean singletonBean1 = context.getBean("singletonBean", MyBean.class);
        MyBean singletonBean2 = context.getBean("singletonBean", MyBean.class);
        System.out.println(singletonBean1 == singletonBean2); // true

        // Prototype 스코프: 서로 다른 인스턴스를 반환
        MyBean prototypeBean1 = context.getBean("prototypeBean", MyBean.class);
        MyBean prototypeBean2 = context.getBean("prototypeBean", MyBean.class);
        System.out.println(prototypeBean1 == prototypeBean2); // false
    }
}

위 예제에서 singletonBean은 동일한 인스턴스를 반환하며, prototypeBean은 서로 다른 인스턴스를 반환합니다.

Bean Scope의 활용

빈 스코프를 활용하여 필요한 경우에 따라 효율적인 자원 관리가 가능합니다. 예를 들어, 애플리케이션 전역에서 사용하는 로깅이나 설정 관리와 같은 빈은 싱글톤으로 설정하고, 사용자의 요청이나 세션에 따라 생성되는 빈은 프로토타입 또는 세션 스코프로 설정하는 것이 좋습니다.

참고

코드 참조

package org.example.di02;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

@SpringBootApplication
public class Di05Application {

    public static void main(String[] args) {
        SpringApplication.run(Di05Application.class, args);

        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeanConfig.class);

        // 싱글톤 Scope : 같은 참조, 항상 같은 인스턴스
        HelloBean1 helloBean11 = context.getBean("helloBean1", HelloBean1.class);
        HelloBean1 helloBean12 = context.getBean("helloBean1", HelloBean1.class);

        System.out.println(helloBean11);  // org.example.di02.HelloBean1@3f14c570
        System.out.println(helloBean12);  // org.example.di02.HelloBean1@3f14c570

        // 프로토타입 Scope: 다른 참조, 다른 인스턴스
        HelloBean2 helloBean21 = context.getBean("helloBean2", HelloBean2.class);
        HelloBean2 helloBean22 = context.getBean("helloBean2", HelloBean2.class);

        System.out.println(helloBean21);  // org.example.di02.HelloBean2@8a58114
        System.out.println(helloBean22);  // org.example.di02.HelloBean2@2f597247

        context.close();
    }

}

0개의 댓글

관련 채용 정보