메서드 호출 방식의 차이 (자바 vs 스프링)
- 질문 : 순수 자바의
instance.method()
와 스프링의 메서드 호출은 어떻게 다른가? - 정리 : 메서드를 호출하는 코드(
instance.method()
) 자체는 동일하다. 근본적인 차이는 인스턴스를 누가 만들고 관리하느냐에 있다. 자바는 개발자가 직접new
로 만들지만, 스프링은 프레임워크가 대신 만들어 주입(Inject)해준다.
주입의 본질 (IoC/DI)
- 질문 :
new
를 안 쓰는 게 핵심 차이인가? - 정리: 그렇다. 개발자가 객체를 직접 생성하고 제어하는 대신, 그 제어권을 스프링 프레임워크에게 넘기는 것, 이것이 바로 제어의 역전(IoC: Inversion of Control)이다. 그리고 필요한 객체를 외부(스프링 컨테이너)에서 넣어주는 행위가 의존성 주입(DI: Dependency Injection)이다.
객체 간의 관계 (참조)
- 질문 : 의존성을 주입받은 인스턴스는 여러 인스턴스가 합쳐진 하나의 거대한 인스턴스인가?
- 정리 : 절대 아니다. 각 인스턴스(Bean)는 독립적인 객체이며, 다른 객체의 메모리 주소(참조, Reference)만을 갖는다. 이는 자바의 참조 타입(Reference Type)이 동작하는 기본 원리이며, 객체들은 서로의 주소를 통해 '협력'하는 관계다.
상태 관리의 원칙 (Stateless Beans & Thread Safety)
- 질문 : 외부에서 빈의 내용을 바꿀 수 있는가? 그렇다면 상태(State)는 어디에 저장해야 하는가?
- 정리 : 기술적으로는 가능하지만, 그래서는 안 된다. 스프링의 빈은 기본적으로 싱글톤(Singleton)이므로, 여러 요청(스레드)이 하나의 인스턴스를 공유한다. 빈이 상태를 가지면(Stateful) 스레드 안전성 문제가 발생해 데이터가 오염된다. 따라서 빈은 반드시 상태가 없도록(Stateless) 설계하고, 상태는 그 목적에 맞게 데이터베이스, Redis, HTTP 세션 등 전문 저장소에 위임해야 한다.
빈(Bean) 생성과 의존성 주입(DI)의 핵심 정의
- 질문 : 스프링의 자동 생성은 클래스를 빈으로 만드는 과정이고, 주입은 변수에 빈을 할당하는 과정인가?
- 정리 : 그렇다. 이 두 문장은 스프링
DI
의 핵심을 가장 잘 요약한 표현이다.- 빈 생성 : 스프링이 클래스(설계도)를 보고 객체 인스턴스(제품)를 만들어 자신의 컨테이너에 등록하는 과정이다.
- 의존성 주입 : 스프링이 한 빈(A)이 필요로 하는 다른 빈(B)의 참조(주소값)를 A의 변수나 생성자 매개변수에 대신 할당(연결)해주는 행위이다.
의존성 주입 방식 : 생성자 주입을 써야 하는 이유
- 질문 :
Setter
주입은 왜 생성자 주입보다 번거롭게 동작하는가? - 정리 :
Setter
주입은 과거XML
기반 설정의 유산이며, 현대적인 관점에서는 생성자 주입 방식이 훨씬 우월하기 때문에 번거롭게 느껴지는 것이 맞다.- 생성자 주입의 장점
- 불변성 확보 (final 사용 가능)
- 의존성 누락 방지 (NPE 원천 방지)
- 테스트 용이성
- 이러한 장점 때문에 생성자 주입이 현재 가장 강력하게 권장되는 Best Practice다.
- 생성자 주입의 장점
선택적 의존성 : Optional의 역할
- 질문 : 선택적인 의존성은 왜 필요한가?
Optional
은 생성자 주입의 특별한 방법인가? - 정리
Optional
은 스프링 기능이 아닌 자바 8의 기본 기능으로,null
이 될 수 있는 값을 안전하게 감싸는 '상자'다.- 이 '상자'를 생성자 주입에 활용하면 "있어도 되고 없어도 되는" 선택적 의존성을 가장 명확하고 안전하게 표현할 수 있다.
- 필요 이유 : 핵심 기능에 영향을 주지 않으면서, 특정 조건이 만족될 때만 부가 기능(플러그인)을 활성화하는 유연하고 확장 가능한 소프트웨어를 만들기 위해 필요하다.
조건부 기능 활성화 : @Profile의 활용
- 질문: 유료 기능처럼 특정 상황에서만 기능을 활성화하려면 어떻게 하는가? 프리미엄 등급이 골드 등급의 기능을 포함하는 계층 구조는 어떻게 구현하는가?
- 핵심 정리 : 스프링의 프로필(Profile) 기능을 사용하면 설정 파일의 값에 따라 빈의 생성을 제어할 수 있다.
@Profile("paid")
: 특정 클래스에 붙여두면, paid 프로필이 활성화될 때만 해당 빈이 생성된다.- 계층 구조 해결 : 프로필 그룹(Profile Groups)을 사용하면 된다.
application.properties
에spring.profiles.group.premium=gold,basic
과 같이 정의하면, premium 프로필만 활성화해도 gold와 basic 프로필이 자동으로 함께 활성화되어, 등급별 기능 포함 관계를 깔끔하게 구현할 수 있다.
'Spring' 카테고리의 다른 글
스프링 빈의 종류 : 스코프 (1) | 2025.06.10 |
---|---|
인스턴스 생명 주기와 애너테이션 : 한눈에 보기 - 콜백 (1) | 2025.06.09 |
[3편] 좋은 DI 설계: 스프링의 빈 탐색 원리와 OCP (0) | 2025.06.03 |
[2편] 스프링 DI의 3가지 방식 : 생성자 주입을 써야만 하는 이유 (0) | 2025.06.03 |
[1편] 의존성 주입(DI)과 제어의 역전(IoC), 왜 필요할까? (0) | 2025.06.02 |