241011 내일배움캠프 백엔드 Java 6기 TIL : Spring Bean & Singletone

박대현·2024년 10월 11일
0

Spring Boot에서 빈(bean)이 기본적으로 싱글톤(Singleton)으로 등록되는 이유는 의존성 주입(DI: Dependency Injection)애플리케이션 성능을 고려한 설계 원칙 때문

1. 싱글톤 빈(Singleton Bean)의 정의

  • 싱글톤 빈이란 애플리케이션 구동 시 딱 한 번만 생성되고, 애플리케이션이 종료될 때까지 동일한 객체 인스턴스가 사용되는 빈을 말함.
  • Spring에서는 빈을 만들 때 기본적으로 싱글톤 스코프를 적용하여, 해당 빈에 대해 하나의 인스턴스만 생성하도록 보장.

2. 싱글톤으로 등록되는 이유

A. 메모리 및 성능 최적화

  • 싱글톤 스코프를 사용하면 메모리를 절약할 수 있음.
  • 각 빈마다 새로운 인스턴스를 생성하는 대신, 한 번 생성된 인스턴스를 계속해서 재사용하기 때문에 메모리 사용량이 줄어듬.
  • 또한, 빈을 재사용할 수 있기 때문에 객체를 매번 생성하는 오버헤드를 줄일 수 있어 애플리케이션 성능이 향상.

B. 의존성 주입 간결성

  • 의존성 주입(DI)을 통해 Spring은 여러 컴포넌트 간의 복잡한 객체 의존성을 관리하는데, 빈이 싱글톤으로 관리되면 이 과정이 단순해짐.
  • 각 빈의 인스턴스를 한 번만 생성하고 이를 재사용하기 때문에 트랜잭션 관리, 캐시, 세션 관리와 같은 부분에서 일관성을 유지할 수 있음.

* 다른 스코프

  • Spring에서는 싱글톤 외에도 다양한 스코프를 제공
    • Prototype: 요청할 때마다 새로운 인스턴스를 생성
    • Request: 웹 요청 하나당 하나의 빈 인스턴스를 생성
    • Session: 웹 세션 하나당 하나의 빈 인스턴스를 생성
    • Application: 웹 애플리케이션당 하나의 빈을 생성

4. 싱글톤 스코프의 단점

  • 만약 상태를 가지는 빈을 싱글톤으로 사용할 경우, 다른 요청이나 스레드에서 빈의 상태가 공유되어 예상치 못한 동작을 유발할 수 있음.
  • 이러한 상태가 있는 빈prototype 스코프로 관리하거나, 상태를 별도로 관리하는 것이 중요합니다.

5. 상태를 가진다?

  • "상태를 가진다"는 말은 객체가 인스턴스 변수(필드)에 값을 저장하여 그 값이 시간에 따라 변할 수 있는 것을 의미.
  • 이러한 상태는 객체가 특정 시점에서 어떠한 값을 유지하고 있다는 뜻. 시간이 지남에 따라 변할 수 있다는 뜻.
  • 상태를 가진 객체는 여러 요청이나 스레드에서 동시에 사용될 때, 그 상태가 공유되므로 예기치 않은 동작을 초래할 수 있음.

상태를 가진 빈의 예

  • 이 빈은 사용자마다 로그인한 사용자 이름을 저장하고 그 값을 반환하는 기능을 제공
  • 이 빈이 싱글톤으로 등록되어 있을 경우, 여러 사용자 요청이 들어오면 서로 다른 사용자들이 같은 상태를 공유하게 되어 데이터 충돌이 발생.
@Service
public class LoginService {

    private String loggedInUser;  // 상태를 저장하는 필드

    public void login(String username) {
        this.loggedInUser = username;  // 로그인 시 상태를 저장
    }

    public String getLoggedInUser() {
        return this.loggedInUser;  // 현재 로그인한 사용자 반환
    }
}

동작 시나리오

  1. 사용자 A가 로그인하고 login("UserA") 메서드를 호출.
    • loggedInUser 필드에 "UserA"가 저장.
  2. 사용자 B가 로그인하고 login("UserB") 메서드를 호출.
    • loggedInUser 필드 값이 "UserB"로 갱신.
  3. 이제 사용자 AgetLoggedInUser() 메서드를 호출하면, "UserA"가 아니라 "UserB"가 반환.

이처럼 상태를 가진 객체는 싱글톤으로 사용할 때, 여러 사용자가 동시에 접근할 경우 상태가 공유되면서 데이터 충돌이 발생할 수 있음.


무상태 객체의 예

  • 무상태 객체는 필드에 상태를 저장하지 않고, 필요한 데이터를 메서드 파라미터로 처리
  • 이 경우 객체는 요청마다 새로운 데이터를 처리할 뿐, 내부적으로 상태를 유지하지 않음.
@Service
public class CalculationService {

    public int add(int a, int b) {
        return a + b;  // 상태 없이 매번 계산만 함
    }
}

동작 시나리오

  1. 사용자 Aadd(5, 3)을 호출하면, 결과로 8이 반환.
  2. 사용자 Badd(10, 2)을 호출하면, 결과로 12가 반환.
  • 이 객체는 내부에 상태를 저장하지 않기 때문에, 사용자 A와 B의 요청이 서로 영향을 미치지 않음.
    어떠한 사용자 요청에도 상태가 공유되지 않고 독립적으로 처리.

정리

  • Spring Boot에서 빈이 기본적으로 싱글톤으로 등록되는 이유는 메모리 효율성, 성능 향상, 그리고 의존성 주입의 단순화를 위한 것.
  • 싱글톤 스코프는 대부분의 서비스나 리포지토리와 같은 무상태 빈에 적합하며, Spring은 이를 통해 애플리케이션을 효율적으로 관리
  • 상태를 가진 빈이 필요한 경우 프로토타입 스코프를 사용하거나, 상태를 외부에서 관리하는 방식으로 변경하는 것이 좋음.

0개의 댓글