waveofmymind
기록하는 습관
waveofmymind
전체 방문자
오늘
어제
  • 분류 전체보기 (124)
    • 📝 정리 (5)
    • 🌊TIL (9)
    • 💻CS (1)
      • 자료구조 (1)
    • 📙Language (9)
      • ☕Java (6)
      • 🤖Kotlin (3)
    • 🍃Spring (28)
    • 👨🏻‍💻알고리즘 (67)
      • 프로그래머스 (59)
      • 백준 (3)
    • 👷DevOps (4)
      • 🐳Docker (2)
      • 🤵Jenkins (1)

블로그 메뉴

  • 홈
  • Spring
  • Java
  • 알고리즘

공지사항

인기 글

태그

  • Open AI
  • 코틀린
  • Connection
  • 힙
  • 다이나믹 프로그래밍
  • 챗GPT
  • CORS
  • 스프링 시큐리티
  • mybatis
  • Spring Security
  • SpringAOP
  • 트랜잭션
  • 스택
  • spring
  • chat GPT
  • AOP
  • JDBC
  • kotlin
  • 스프링 부트
  • 완전탐색
  • 트랜잭션 전파
  • resultset
  • BFS
  • spring boot
  • LeetCode
  • til
  • 스프링
  • sql
  • kotest
  • 통합테스트

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
waveofmymind

기록하는 습관

🍃Spring

[Spring] 스프링 빈 스코프 (2/2)

2023. 5. 27. 10:13

스프링 빈 스코프

스프링에서 싱글톤과 프로토타입 빈 스코프를 제공하고 있으며, 스프링 MVC 웹 애플리케이션을 사용할 경우 웹 스코프를 제공한다.

 

싱글톤

  • 싱글톤 빈은 스프링 컨테이너에서 한 번만 생성되며, 컨테이너가 사라질 때 제거된다.
  • 생성된 하나의 인스턴스는 Spring Beans Cache에 저장되고, 해당 빈에 대한 요청과 참조가 있으며 캐시된 객체를 반환한다. 하나만 생성되기 떄문에 동일 참조를 보장한다.
  • 기본적으로 모든 빈은 스코프가 명시적으로 지정되지 않으면 싱글톤이다.
  • 대상 클래스에 @Scope("singletone")을 붙이면 된다.
  • 싱글톤으로 적합한 객체는 아래와 같다.
    • 상태가 없는 공유 객체
    • 읽기 전용으로만 상태를 가진 객체
    • 쓰기가 가능한 상태를 지니면서도 사용 빈도가 매우 높은 객체
      • 동기화 전략이 필요하다.

프로토타입

  • 프로토타입 빈은 DI가 발생할 때마다 새로운 객체가 생성되어 주입된다.
  • 빈 소멸에 스프링 컨테이너가 관여하지 않고, GC에 의해 빈이 제거된다.
  • 대상 클래스에 @Scope("prototype")을 붙이면 된다.
  • 프로토타입으로 적합한 객체
    • 사용할 때마다 상태가 달라져야 하는 객체
    • 쓰기가 가능한 상태가 있는 객체

싱글톤 빈과 프로토타입 빈을 같이 사용할 때 생기는 문제

  • 프로토타입 객체가 싱글톤 객체를 가지고 있는것은 문제가 되지 않는다.
  • 반대로 싱글톤 객체가 프로토타입 객체를 가지고 있는 경우, 의도한 것과 다른 결과를 낼 수 있다.
    • 싱글톤 빈으로 생성되는 시점에 프로토 타입 빈이 생성되어 있기 때문에 싱글톤 빈 내부의 프로토타입 빈을 호출하게 되면 매번 같은 값을 가져오게 된다. 

웹 스코프

  • 스프링이 사용하는 싱글톤 스코프는 스프링 컨테이너의 시작부터 끝까지 함께하는 스코프이고, 프로토타입 스코프는 생성과 의존 관계 주입 및 초기화까지만 진행하는 스코프이다.
  • 웹 스코프는 웹 환경에서만 동작하는 스코프이며 프로토타입과 다르게 특정 주기가 끝날 때까지 관리를 해준다. 따라서 @PreDestroy와 같이 소멸 콜백이 호출된다는 특징이 있다.
  • 웹 스코프의 종류
    • Request
      • HTTP 요청 하나가 들어오고 나갈때까지 유지되는 스코프
      • 각각의 HTTP 요청마다 별도의 빈 인스턴스가 생성되고 관리된다.
    • Session
      • HTTP Session과 동일한 생명 주기를 가지는 스코프
    • Application
      • 서블릿 컨텍스트와 동일한 생명 주기를 가지는 스코프
    • WebSocket
      • 웹 소켓과 동일한 생명 주기를 가지는 스코프

스프링 빈의 생명 주기

싱글톤 빈

싱글톤 빈의 생명 주기는 다음과 같다.

싱글톤 빈의 생명주기

  1. 스프링 컨테이너 생성
  2. 스프링 빈 생성
  3. 의존관계 주입
  4. 초기화 콜백
  5. 사용
  6. 소멸 전 콜백
  7. 스프링 종료

스프링 컨테이너가 생성되고, 스프링 빈이 등록되어 의존 관계가 주입되는 사실은 익숙하지만, 소멸 전 콜백에 대해서 알아보자.

@Component
public class OrderServiceImpl implements OrderService {

    private final DiscountPolicy discountPolicy;

    public OrderServiceImpl(DiscountPolicy discountPolicy) {
        this.discountPolicy = discountPolicy;
    }

    @Override
    public Order createOrder(int age, String itemName, int itemPrice) {
        int discountPrice = discountPolicy.discount(age, itemPrice);
        return new Order(itemName, itemPrice, discountPrice);
    }
    
    @PostConstruct
    public void init() {
        System.out.println("초기화 콜백입니다.");
    }
    
    @PreDestroy
    public void close() {
        System.out.println("소멸 전 콜백입니다.");
    }
}

위 코드와 같이 @PostConstruct를 사용하면 초기화 콜백이 호출되고, @PreDestroy를 호출하면 소멸전 콜백이 호출된다.

프로토타입 빈

프로토타입 빈 생명주기

프로토 타입 빈은 스프링 컨테이너가 빈 생성까지만 관리하고, 그 이후에는 제어권이 사라진다.

  1. 스프링 컨테이너 생성
  2. 스프링 빈 생성
  3. 의존 관계 주입
  4. 초기화 콜백
  5. 사용
  6. GC에 의한 수거

싱글톤 빈은 Thread-safe한가?

public class Singleton {

    private static Singleton instance = new Singleton();
    
    private Singleton() {
    }

    public static Singleton getInstance() {
        return instance;
    }
}

싱글톤 패턴은 위와 같으며, 전체 애플리케이션 중 단 한번만 초기화되어 애플리케이션이 종료될 때까지 메모리에 상주하게 된다.

만약 싱글톤이 상태를 갖게 되면 멀티쓰레드 환경에서 동기화 문제가 발생할 수 있다.

 

스프링에서는 별다른 설정을 하지 않을 경우 디폴트가 싱글톤으로 빈이 관리된다. 그런데, 싱글톤 빈을 사용할 때 private 생성자, static 변수, static 메서드를 정의하지 않고도 싱글톤으로 사용한다.

그래서 간혹 싱글톤 빈은 상태를 가져도 Thread-safe할 것이라는 착각을 하는 경우가 있다.

 

결론은 스프링은 싱글톤 레지스트리를 통해 private 생성자, static 변수 등의 코드 없이 비즈니스 로직에 집중하고 테스트 코드에 용이한 싱글톤 객체를 제공해주는 것 뿐이지, 동기화 문제는 우리가 처리해야한다.

만약 싱글톤 빈이 상태를 갖게되고, 아무런 동기화 처리를 하지 않는다면 멀티 쓰레드 환경에서 부작용이 발생할 수 있다.

출처

https://taes-k.github.io/2020/06/14/spring-bean-scope-lifecycle/

 

Scope에 따른 Spring bean life-cycle

Spring bean bean의 life-cycle을 알아보기에 앞서서 bean의 개념부터 간단하게 알아보도록 하겠습니다. (해당 포스팅 내용은 정확한 내용 전달을 위해 Spring doc 내용을 발췌 번역한 내용임을 알립니다. -

taes-k.github.io

 

'🍃Spring' 카테고리의 다른 글

[Spring] IoC와 DI (2/2)  (0) 2023.05.29
[Spring] IoC와 DI (1/2)  (0) 2023.05.27
[Spring] 스프링 빈 (1/2)  (0) 2023.05.26
[Spring] 테스트 클렌징시 deleteAll()을 사용할 때의 주의점  (0) 2023.05.13
[Spring] WebMvcTest에서 발생하는 SpringSecurity 의존성 문제 해결하기  (0) 2023.04.19
    '🍃Spring' 카테고리의 다른 글
    • [Spring] IoC와 DI (2/2)
    • [Spring] IoC와 DI (1/2)
    • [Spring] 스프링 빈 (1/2)
    • [Spring] 테스트 클렌징시 deleteAll()을 사용할 때의 주의점
    waveofmymind
    waveofmymind

    티스토리툴바