Daily Dev Q&A: Spring Bean

2025. 12. 26. 17:00·Archive/Daily Dev Q&A

Topic (오늘의 주제)

Spring Bean (스프링 빈)

: Spring IoC 컨테이너가 생성하고, 관계를 설정하고, 관리하는 자바 객체.

Why (왜 사용하는가? 왜 중요한가?)

  • 실무: 개발자가 new 키워드로 객체를 매번 생성하면 메모리 낭비가 심하고 의존성 관리가 힘들다. 빈으로 등록하면 **싱글톤(Singleton)**으로 관리되어 메모리를 절약하고 **의존성 주입(DI)**을 받을 수 있다.
  • 구조적 의미: 일반적인 자바 객체(POJO)와 다를 바 없지만, "컨테이너의 관리 하에 있다"는 점이 핵심이다. 즉, 태어나고 죽는(Lifecycle) 것을 스프링이 책임진다.
  • 면접 의도: 빈이 무엇인지 정의하고, 일반 객체와의 차이점, 그리고 빈을 등록하는 방법(@Component vs @Bean)을 아는지 확인한다.

Core Concept (핵심 개념 정리)

일반 객체와 빈의 가장 큰 차이는 "누가 관리하느냐(IoC)"입니다.

요소 내용
개념 정의 Spring IoC 컨테이너(ApplicationContext) 안에 들어있는 객체.
등록 방법 1. Component Scan: @Component 클래스 위 부착.

2. Configuration: @Configuration 내부 메서드에 @Bean 부착.
관리 방식 기본적으로 싱글톤(Singleton). 즉, 애플리케이션 전체에서 딱 1개만 생성되어 공유된다.
생명주기 생성 → 의존성 주입 → 초기화(@PostConstruct) → 사용 → 소멸(@PreDestroy)

1. 관리 방식의 핵심: 싱글톤 (Singleton)

"딱 하나만 만들어서 다 같이 돌려 쓴다"

  • 개념: 메모리에 객체를 딱 1개만 생성해두고, 어디서 요청하든 그 1개를 계속 재사용하는 방식입니다.
  • [비유] 정수기 vs 생수병:
    • 일반 객체 (new): 목마른 사람이 100명 오면 생수병 100개를 나눠줌 (메모리 낭비).
    • 싱글톤 (빈): 사무실에 정수기 1대를 놓는 것. 100명이 오든 1000명이 오든 그 하나의 정수기를 공유함 (메모리 절약).
  • ⚠️ 주의할 점 (Stateless): 정수기에 누가 빨간 물감을 타면(상태 변경), 뒤에 오는 사람도 모두 빨간 물을 마시게 됩니다(동시성 이슈). 그래서 싱글톤 빈은 공유해도 안전하게끔 읽기 전용(Read-only) 상태를 유지해야 합니다.

2. 등록 원리의 핵심: 메서드(Method)와 @Bean

"객체가 하는 행동" vs "객체를 만드는 공장"

@Configuration 클래스 안에서 사용하는 @Bean은 메서드 위에 붙습니다. 이때의 메서드는 일반적인 기능(로그인, 저장 등)이 아니라 "객체 생성 공장(Factory)" 역할을 합니다.

  • 작동 원리: 스프링 컨테이너는 @Bean이 붙은 메서드를 호출(실행)합니다.
  • 결과: 이때 메서드가 반환(Return)하는 결과물을 낚아채서 '스프링 빈'으로 등록합니다. 즉, "이 메서드를 실행하면 나오는 결과물을 빈으로 써줘"라는 의미입니다.

💡 비교: @Component vs @Bean (빈 등록의 두 가지 방법)

이 차이를 묻는 질문이 정말 많이 나옵니다.

구분 @Component @Bean
위치 클래스 위 메서드 위 (주로 @Configuration 클래스 내부)
용도 내가 작성한 클래스를 빈으로 등록할 때 외부 라이브러리 객체(예: ObjectMapper)를 빈으로 등록할 때
제어권 클래스 자체에 붙일 수 있어 간편함 소스 코드를 수정할 수 없는 외부 클래스를 등록할 때 유용함

🚀 [실전 가이드] 언제 무엇을 써야 할까?

가장 쉬운 판단 기준: "이 클래스 파일(.java), 내가 직접 짠 건가?"

Case 1: @Component (내 코드)

  • 상황: 내가 직접 작성한 클래스이므로 파일을 열어서 코드를 수정할 수 있습니다.
  • 방법: 클래스 위에 @Component (또는 @Service, @Controller)를 직접 붙이면 됩니다.
  • Java
    @Service // 직접 붙이면 끝!
    public class MemberService { ... }
    

Case 2: @Bean (외부 라이브러리)

  • 상황: jar 파일로 가져온 라이브러리(예: ObjectMapper)는 읽기 전용이라 소스에 스티커를 붙일 수 없습니다.
  • 방법: @Configuration 파일 안에서 메서드를 만들고 "이 객체 생성해서 써줘"라고 수동으로 등록해야 합니다.
  • Java
    @Configuration
    public class AppConfig {
        @Bean // 메서드가 반환하는 객체를 빈으로 등록
        public ObjectMapper objectMapper() {
            return new ObjectMapper();
        }
    }
    

Interview Answer Version (면접 답변식 요약)

"Spring Bean은 스프링 IoC 컨테이너가 관리하는 자바 객체를 말합니다.

우리가 흔히 쓰는 new 연산자로 만든 객체와 달리, 빈은 컨테이너가 생성부터 소멸까지의 생명주기를 관리해 줍니다. 기본적으로 싱글톤(Singleton) 스코프로 생성되어 메모리를 효율적으로 사용하며, 이를 통해 의존성 주입(DI)이나 AOP 같은 스프링의 핵심 기능을 적용받을 수 있습니다."

Practical Tip (사용시 주의할 점 or 활용 예)

1. 상태를 가지면 안 된다 (Stateless) 빈은 기본적으로 **싱글톤(하나를 모두가 공유)**입니다.

  • 위험: 빈 안에 수정 가능한 멤버 변수(상태)를 두면, A 사용자가 요청한 데이터가 B 사용자에게 보이는 치명적인 동시성 이슈가 발생합니다.
  • 해결: 빈의 필드는 주로 readonly(읽기 전용)이거나, 다른 빈을 참조하는 용도로만 써야 합니다. 상태값은 메서드 파라미터나 지역 변수로 처리해야 합니다.

2. 초기화 작업은 생성자가 아니라 @PostConstruct에서 생성자 호출 시점에는 아직 **DI(의존성 주입)**가 완료되지 않았을 수도 있습니다. (물론 생성자 주입을 쓰면 보장되긴 합니다.) 빈이 생성되고 의존성 주입까지 완벽히 끝난 후, 초기 데이터를 로딩하거나 설정을 검증하고 싶다면 @PostConstruct 어노테이션이 붙은 메서드에서 수행하는 것이 안전합니다.

예상 꼬리 질문 정리

  • "스프링 빈은 모두 싱글톤인가요? 다른 스코프는 없나요?"
    • (기본은 싱글톤이지만, 요청할 때마다 새로 만드는 Prototype, HTTP 요청마다 만드는 Request 스코프 등이 있음을 설명)
  • "Bean Lifecycle(생명주기)에 대해 설명해 주세요."
    • (객체 생성 → 의존성 주입 → 초기화 콜백 → 사용 → 소멸 콜백 순서를 아는지 확인)
  • "같은 타입의 빈이 2개 이상 있으면 어떻게 되나요?"
    • (NoUniqueBeanDefinitionException 발생. 해결책으로 @Primary나 @Qualifier 사용 언급)

Deep Dive (공부하며 몰랐던 개념)

1. 스코프 (Scope)

"이 객체가 언제 태어나서, 언제까지 살아있고, 어디까지 적용되는가?"

영어 단어 Scope는 '범위'나 '영역'이라는 뜻입니다. 스프링 빈에서 스코프는 "빈의 생존 기간과 범위"를 결정하는 규칙입니다. 쉽게 말해, "달라고 할 때마다 똑같은 걸 줄 거냐(싱글톤), 아니면 매번 새것을 줄 거냐(프로토타입)"를 정하는 것입니다.

[비유] 치킨집으로 이해하는 스코프 🍗

치킨집 사장님(스프링 컨테이너)이 주방 도구를 관리하는 방식에 비유할 수 있습니다.

  • ① 싱글톤 (Singleton) 스코프 (기본값)
    • 비유: 튀김기
    • 상황: 주문이 100개가 들어와도 튀김기는 딱 1대만 두고 돌려 씁니다.
    • 특징: 앱이 켜질 때 생성되어 꺼질 때까지 계속 재사용됩니다. 누가 달라고 해도 항상 그 튀김기를 줍니다. (효율성)
  • ② 프로토타입 (Prototype) 스코프
    • 비유: 치킨 포장 박스
    • 상황: 손님이 올 때마다(요청할 때마다) 새 박스를 꺼내서 줍니다.
    • 특징: 달라고 할 때마다 새로운 객체를 생성해서 던져줍니다. 스프링은 생성까지만 관여하고, 그 뒤로는 관리하지 않습니다.
  • ③ 리퀘스트 (Request) 스코프 (웹 전용)
    • 비유: 주문서(영수증)
    • 상황: 손님 A가 들어와서 나갈 때까지만 유효합니다. 손님 B의 주문서와 섞이면 안 됩니다.
    • 특징: HTTP 요청이 한 번 들어오고 나갈 때까지만 살아있습니다. 각 사용자의 요청을 격리해야 할 때 사용합니다.

[한눈에 비교하기]

구분 싱글톤 (Singleton) 프로토타입 (Prototype)
생성 갯수 딱 1개 요청할 때마다 무한 생성
수명 애플리케이션 시작 ~ 끝 (장수) 필요할 때 생성 ~ 사용 후 바로 잊혀짐 (단명)
공유 여부 모두가 공유함 나만을 위한 객체 (공유 안 함)
주요 용도 서비스, 컨트롤러 등 (대부분) 상태 저장이 필요한 특수한 경우

'Archive > Daily Dev Q&A' 카테고리의 다른 글

Daily Dev Q&A: Spring의 예외 처리 방식  (0) 2025.12.29
Daily Dev Q&A: Spring Stereotype Annotations  (0) 2025.12.29
Daily Dev Q&A: Spring Boot  (0) 2025.12.26
Daily Dev Q&A: IoC & DI  (0) 2025.12.26
Daily Dev Q&A: Spring Framework  (0) 2025.12.23
'Archive/Daily Dev Q&A' 카테고리의 다른 글
  • Daily Dev Q&A: Spring의 예외 처리 방식
  • Daily Dev Q&A: Spring Stereotype Annotations
  • Daily Dev Q&A: Spring Boot
  • Daily Dev Q&A: IoC & DI
tlsgkstj
tlsgkstj
짱구의 성장 일기
  • tlsgkstj
    코딩하는 짱구
    tlsgkstj
  • 전체
    오늘
    어제
    • 분류 전체보기 (159)
      • About (1)
      • Projects (35)
        • Personal Projects (21)
        • Team Projects (14)
      • Engineering (20)
        • CS & Tools (0)
        • Backend Core (15)
        • Frontend (1)
        • Infra & Cloud (2)
        • AI & Tools (1)
      • Trouble Shooting & Issues (0)
      • Growth & Career (38)
        • Interview Prep (0)
        • Retrospectives (38)
      • Archive (65)
        • TIL (8)
        • Daily Dev Q&A (56)
  • 블로그 메뉴

    • 홈
    • About
    • Projects
    • Tech Stack
    • Dev Log
    • GitHub
  • 링크

    • github
  • 공지사항

  • 인기 글

  • 태그

    프로덕트개발자
    경기기후바이브코딩
    DevFestIncheon2025
    backend
    spring
    jpa
    Project_Review
    Spring비교
    java
    데브페스트
    REACT
    커리어리셋
    til
    network
    aws_s3
    클로드코드
    OrphanRemova
    devlog
    SpringBoot
    프로젝트회고
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
tlsgkstj
Daily Dev Q&A: Spring Bean
상단으로

티스토리툴바