스프링 컨테이너와 빈(Bean) - 싱글톤과 의존관계 주입 방법

Computer Science/Spring Boot

싱글톤(Singleton) 컨테이너

스프링의 컨테이너는 싱글톤 컨테이너라고도 부른다. 그 이유는 단순하게 컨테이너에서 객체들을 싱글톤으로 관리해주기 때문이다. 그럼 여기서 싱글톤이란 무엇인지 알아보자.

 

싱글톤(Singleton)

이번에도 구글 찬스

싱글톤이란 하나의 클래스에서 단 하나의 객체 인스턴스만 생성하도록 보장하는 디자인 패턴이다.

왜 이런 방식을 사용할까? 싱글톤이 아니라면 다음과 같은 상황이 일어날 수 있다.

만약 여러 클라이언트가 memberService가 필요한 요청을 보냈다고 생각해보자. 그러면 스프링은 매 요청마다 memberService를 생성하고 응답을 보낼 것이다. 이런 방식은 사용자가 늘어나면 늘어날 수록 메모리 낭비가 심하다. 이것을 해결하기 위해 등장한 패턴이 바로 싱글톤 패턴이다.

 

그럼 어떻게 싱글톤을 구현하는지 아래 싱글톤 예제를 확인해보자.

싱글톤 예제

이렇게 클래스를 생성할 때 static으로 본인 인스턴스를 가지는 필드를 생성한다. 주의할 점은 만약 여기서 static이 빠진다면 객체가 생성되면서 필드에 또 본인을 생성하는 무한 루프가 일어나기 때문에 꼭 static 키워드를 사용해서 jvm의 method 영역에 생성해야한다.

만약 이 객체의 인스턴스가 필요하다면 생성자는 private로 만들어 새로운 객체 생성을 막고 오직 getInstance()를 호출해서 사용하도록 강제하면 싱글톤의 완성이다.

 

하지만 싱글톤 패턴을 위처럼 직접 구현하려면 모든 클래스에 이런 부가적인 코드를 달아줘야하고 의존관계를 설정할 때 getInstance로 직접 작성해주어야 하기 때문에 DIP를 위반한다는 단점이 있다.

 

컨테이너가 관리하는 싱글톤

하지만 스프링 컨테이너는 위에 나열한 문제들을 해결하면서 객체를 싱글톤으로 관리한다. 이전에 학습했던 빈(Bean)이 싱글톤으로 관리되는 빈이다. 컨테이너가 빈들을 싱글톤으로 관리해주기 때문에 우리는 직접 코드를 추가로 작성할 필요가 없고 DIP도 해결된다.

컨테이너가 관리하는 싱글톤

스프링 컨테이너는 다음과 같은 방식으로 객체를 싱글톤으로 관리한다.

 

기본 스코프 = singleton

  • @Component, @Bean 등으로 등록된 빈은 기본이 singleton 스코프
  • “프로세스 전체 1개”가 아니라 컨테이너당 1개 (테스트용 Context를 두 개 띄우면 각각 1개씩 생김)

생성 시점과 캐싱

  • 컨테이너 시작 시 refresh() → preInstantiateSingletons() 단계에서 싱글톤 빈을 생성(지연 로딩 @Lazy면 필요할 때)
  • 만들어진 인스턴스는 DefaultSingletonBeanRegistry가 갖는 캐시(Map) 에 저장
    • singletonObjects : 완성된 싱글톤
    • earlySingletonObjects / singletonFactories : 순환 참조 처리 등 임시 단계용
  • 이후 getBean()이 오면 새로 만들지 않고 캐시에서 반환

라이프사이클 훅

  • 생성 → 의존성 주입 → BeanPostProcessor (예: 프록시 적용) → 초기화(InitializingBean/@PostConstruct) → 사용 → 컨텍스트 종료 시 @PreDestroy/DisposableBean 호출.

스레드 안전성

  • 싱글톤 캐시는 ConcurrentHashMap 등으로 관리되고, 생성 구간은 컨테이너가 동기화해 한 번만 생성되게 보장
  • 빈 자체의 상태는 불변/무상태로 설계하는 게 원칙(공유 가변 상태는 동시성 버그가 생김)

싱글톤이 아닌 다른 스코프

  • @Scope("prototype") : 요청 때마다 새로 생성(컨테이너는 생명주기 후처리/소멸 관리 안 함).
  • 웹 컨텍스트: request, session, application 스코프 등도 존재

정리하자면 컨테이너가 한 컨테이너당 한 번만 만든 객체를 캐시에 보관해 재사용해서 싱글톤처럼 동작시킨다.

(여기서 캐시라는 말은 스프링이 계속 들고있는다는 뜻의 캐시이고 실제 redis와 같은 캐시가 아님)

 

@Configuration과 싱글톤

근데 @Configuration으로 등록한 파일을 확인해보면 뭔가 이상한 점을 느낄 수 있다.

빈 설정 파일

memberService()도 memberRepository()를 호출하고 orderService()도 memberRepository()를 호출한다. memberRepository()는 new로 생성하니까 두 개가 생성되는게 아닌가?

하지만 직접 실행해서 확인해본다면 모두 같은 객체인 것을 확인할 수 있다.

 

그 이유는 스프링이 CGLIB이라는 바이트코드 조작 라이브러리를 사용해서 같은 싱글톤을 반환하도록 한다. 우리가 @Configuration을 달아서 만든 빈 설정 파일은 빈으로 등록되고 빈 클래스를 조회해보면 다음과 같이 나온다.

원래라면 Appconfig 라는 단일 클래스로 나와야하는데 뒤에 뭔가 달려서 나온다. 이게 바로 CGLIB을 이용해서 우리가 만든 설정 파일을 상속하는 임의의 프록시 객체를 빈으로 등록한다. 내부 코드를 다음과 같이 간단하게 예상해볼 수 있다.

물론 실제로는 훨씬 복잡할 것이다.

 

그럼 빈을 설정하는 파일은 다음과 같이 정리할 수 있다. @Configuration 클래스는 CGLIB으로 프록시되어 @Bean 메서드 여러 번 호출해도 같은 싱글톤을 반환(중복 생성 방지)

'Computer Science > Spring Boot' 카테고리의 다른 글

JPA N+1 문제  (0) 2025.09.02
Spring MVC와 Servlet  (0) 2025.08.29
스프링 컨테이너와 빈(Bean) - Lifecycle Callback과 Scope  (0) 2025.08.24
스프링 컨테이너와 빈(Bean) - ApplicationContext 동작 과정  (0) 2025.08.17
대댓글 페이지네이션  (0) 2025.08.14
'Computer Science/Spring Boot' 카테고리의 다른 글
  • Spring MVC와 Servlet
  • 스프링 컨테이너와 빈(Bean) - Lifecycle Callback과 Scope
  • 스프링 컨테이너와 빈(Bean) - ApplicationContext 동작 과정
  • 대댓글 페이지네이션
hojoo
hojoo
그냥 개발이 즐거운 사람
  • hojoo
    dev_record
    hojoo
  • 전체
    오늘
    어제
    • 분류 전체보기 (84)
      • Study (0)
        • 모든 개발자를 위한 HTTP 웹 기본 지식 (0)
        • Real MySQL 8.0 (0)
        • 친절한 SQL 튜닝 (0)
        • 도메인 주도 개발 시작하기 (0)
        • 대규모 시스템 설계 기초 (0)
      • Computer Science (68)
        • Problem Solving (30)
        • Data Structure (4)
        • Spring Boot (14)
        • DB (1)
        • Java (4)
        • OS (3)
        • Server (3)
        • Tech (0)
      • Security (16)
        • Reversing (15)
        • Assembly (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    x64dbg
    dreamhack.io
    19622
    백준
    DB
    프로그래머스
    소수상근수
    12033
    n^2 배열 자르기
    servlet
    9421
    2539
    16946
    자료구조
    21278
    bean
    PE header
    레나 튜토리얼
    15973
    DP
    13265
    Reversing
    리버싱 핵심원리
    Lena tutorial
    서버 증설 횟수
    HTTP
    n+1
    리버싱
    Spring boot
    Header
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
hojoo
스프링 컨테이너와 빈(Bean) - 싱글톤과 의존관계 주입 방법
상단으로

티스토리툴바