[Spring] Bean Scope란?

지니·2025년 3월 23일

Spring

목록 보기
3/13
post-thumbnail

bean scope이란 스프링 빈이 생성될 때 생성되는 인스턴스의 범위를 의미한다.

🔎 Bean Scope의 종류

여기에서는 SingletonPrototype에 관해서 알아볼 것이다.
1번과 2번은 SingletonPrototype에 관한 설명과 이것들을 자바 파일에서 어떻게 설정하는지에 관한 부분이고 3번은 XML 파일에서 어떻게 설정하는지에 관한 부분이다.

1. SingleTone


스프링 프레임워크에서 Bean의 기본 범위는 singleton이다.

  • 애플리케이션 내에서 하나의 인스터스만을 생성하고 모든 빈이 해당 인스턴스를 공유해 사용한다.
  • 메모리 사용량을 줄일 수 있으며, 성능 향상을 기대할 수 있다.

Scope : 범위를 지정해준다. Singletone이 기본값이다. ⭐
DependsOn : 어떤 빈이 다른 빈보다 먼저 생성될 수 있게 강제화 하는 것이다.
Lazy : 컨테이너 동작 시점이 아닌 해당 객체가 필요한 시점에 인스턴스를 생성할 수 있게 한다.

(1) ContextConfiguration.java

import com.dbwls.common.Beverage;
import com.dbwls.common.Bread;
import com.dbwls.common.Product;
import com.dbwls.common.ShoppingCart;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;

public class ContextConfiguration {
    @Bean
    public Product carpBread() {
        System.out.println("붕어빵 생성 시점");
        return new Bread("붕어빵", 1000, new java.util.Date());
    }
    
    @Bean
    // 만약 이렇게 명시한 빈 중 하나라도 생성되지 않으면, 
    // cart는 생성되지 않고, BeanCreationException이 발생하게 된다.
    @DependsOn({"carpBread", "milk", "water"})
    @Lazy 
    @Scope("singleton") // 기본값
    public ShoppingCart cart() {
        System.out.println("쇼핑 카트 생성 시점");
        return new ShoppingCart();
    }
    @Bean
    public Product milk() {
        System.out.println("딸기우유 생성 시점");
        return new Beverage("딸기우유", 1500, 500);
    }
    @Bean
    public Product water() {
        System.out.println("물 생성 시점");
        return new Beverage("지리산암반수", 3000, 500);
    }
}

(2) Application.java

  • 카트는 손님마다 다르게 가지고 잇어야 한다.
  • 현재 singleton으로 범위가 지정되어 있기 때문에, 고객들이 같은 카트를 공유해서 사용하는 문제가 발생한다.
import com.dbwls.common.Product;
import com.dbwls.common.ShoppingCart;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Application {
    public static void main(String[] args) {
        ApplicationContext applicationContext
                = new AnnotationConfigApplicationContext(ContextConfiguration.class);

        /* 슈퍼에 상품이 진열 되어 있다. */
        Product carpBread = applicationContext.getBean("carpBread", Product.class);
        Product milk = applicationContext.getBean("milk", Product.class);
        Product water = applicationContext.getBean("water", Product.class);

        System.out.println("쇼핑 카트 객체 꺼내기 전");
        /* 쇼핑 카트를 꺼내 상품을 담는다 */
        ShoppingCart shoppingCart = applicationContext.getBean("cart", ShoppingCart.class);
        System.out.println("쇼핑 카트 객체 꺼낸 다음");
        shoppingCart.addItem(carpBread);
        shoppingCart.addItem(milk);
        System.out.println("cart에 담긴 물품 : " + shoppingCart.getItem());

        /* 다음 손님이 와서 쇼핑 카트를 사용한다. */
        ShoppingCart shoppingCart2 = applicationContext.getBean("cart", ShoppingCart.class);
        shoppingCart2.addItem(water);
        System.out.println("cart2에 담긴 물품 : " + shoppingCart2.getItem());

        /* 손님이 바꼈지만 동일한 카트를 사용하고 있음 */
        // 같은 해시코드가 나옴
        System.out.println("1번째 쇼핑 카트의 해시코드 : " + shoppingCart.hashCode());
        System.out.println("2번째 쇼핑 카트의 해시코드 : " + shoppingCart2.hashCode());
    }
}

2. Prototype


필요할 때 마다 새로운 객체를 생성해서 반환하는 것이다. 이를 통해 의존성 주입 등의 작업에서 객체 생성에 대한 부담을 줄일 수 있다.

💡 필요한 순간에만 객체를 생성하므로

  • 초기 로딩 속도가 빨라지고
  • 불필요한 메모리 사용이 줄어들며
  • 멀티스레드 환경에서도 안전하게 객체를 활용

(1) ContextConfiguration.java

  • @Scope("prototype")으로 지정해주면 해당 Bean을 프로토타입으로 인식한다.
import com.dbwls.common.Beverage;
import com.dbwls.common.Bread;
import com.dbwls.common.Product;
import com.dbwls.common.ShoppingCart;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;

public class ContextConfiguration {
    @Bean
    public Product carpBread() {
        return new Bread("붕어빵", 1000, new java.util.Date());
    }
    @Bean
    public Product milk() {
        return new Beverage("딸기우유", 1500, 500);
    }
    @Bean
    public Product water() {
        return new Beverage("지리산암반수", 3000, 500);
    }
    @Bean
    @Scope("prototype") // scope를 prototype으로 지정
    public ShoppingCart cart() {
        return new ShoppingCart();
    }   
}

(2) Application.java

import com.dbwls.common.Product;
import com.dbwls.common.ShoppingCart;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Application {
    public static void main(String[] args) {
        ApplicationContext applicationContext
                = new AnnotationConfigApplicationContext(ContextConfiguration.class);

        /* 슈퍼에 상품이 진열 되어 있다. */
        Product carpBread = applicationContext.getBean("carpBread", Product.class);
        Product milk = applicationContext.getBean("milk", Product.class);
        Product water = applicationContext.getBean("water", Product.class);

        /* 쇼핑 카트를 꺼내 상품을 담는다 */
        ShoppingCart shoppingCart = applicationContext.getBean("cart", ShoppingCart.class);
        shoppingCart.addItem(carpBread);
        shoppingCart.addItem(milk);
        System.out.println("cart에 담긴 물품 : " + shoppingCart.getItem());

        /* 다음 손님이 와서 쇼핑 카트를 사용한다. */
        ShoppingCart shoppingCart2 = applicationContext.getBean("cart", ShoppingCart.class);
        shoppingCart2.addItem(water);
        System.out.println("cart2에 담긴 물품 : " + shoppingCart2.getItem());

        /* 손님이 바뀔 경우 카트가 달라지게 됨 */
        System.out.println("1번째 쇼핑 카트의 해시코드 : " + shoppingCart.hashCode()); // 2028555727
        System.out.println("2번째 쇼핑 카트의 해시코드 : " + shoppingCart2.hashCode()); // 1625082366
    }
}

3. XML 파일 설정


위에서 알아본 것들은 모두 Java코드를 통해 설정하는 방법이다. 만약 java 코드가 아닌 XML 파일을 이용해 applicationContext에게 Configuration metadata를 넘기고 싶다면, bean 태그 안에 scope 상태를 추가해서 원하는 범위를 넣어주면 된다.

(1) xml에서 singleton 설정

<bean id="cart" class="패키지명.ShoppingCart" scope="singleton"/>

(2) xml에서 prototype설정

<bean id="cart" class="패키지명.ShoppingCart" scope="prototype"/>

0개의 댓글