빈과 리플렉션, 그리고 스프링 동작 정리
스프링이 실행될 때 (앱 시작 시점에)
@Component
,@Service
,@Repository
,@Controller
같은 걸 쭉 스캔해서클래스 메타정보(어떤 클래스, 어떤 생성자, 어떤 필드) 를 싹 읽어놓고
빈으로 등록할 대상을 결정한다 (IoC Container에 등록)
나중에 실제 서비스 객체를 사용할 때
필요한 의존성 (ex: 레포지토리, 다른 서비스 등)을
리플렉션을 이용해서 필드 주입, 생성자 주입, 메서드 주입 해준다
서비스 객체는 그냥 "그게 어디서 만들어졌는지" 신경 안 쓰고 바로 쓰기만 하면 된다
공식 용어 :
개념 | 설명 |
---|---|
스프링이 스캔해서 메타정보를 모으는 것 | 컴포넌트 스캔(Component Scan) |
메타정보를 기반으로 객체를 관리하는 것 | IoC (Inversion of Control) 컨테이너 |
필요한 객체를 주입하는 것 | DI (Dependency Injection) |
객체를 가져오는 방식 | 리플렉션 사용 (Field Injection, Constructor Injection, Method Injection) |
📌 좀 더 구조적으로 흐름을 그리면
[1. 컴포넌트 스캔]
@Component, @Service, @Repository 어노테이션 붙은 클래스들 발견
↓
[2. 메타데이터 수집]
클래스 이름, 생성자, 필드, 메서드 정보를 수집 (리플렉션)
↓
[3. 빈 정의(Bean Definition) 생성]
- 어떤 클래스를
- 어떤 방법으로 (생성자 or 빈 팩토리)
- 어떤 의존성을 주입해야 하는지
메타정보로 만들어둠
↓
[4. IoC 컨테이너에 등록]
↓
[5. 실제 사용 시 (DI 단계)]
- 리플렉션으로 생성자 호출하거나
- 필드에 직접 주입하거나
- 세터 메서드 호출하거나
해서 객체를 만들어서 넣어줌
↓
[6. 서비스, 레포지토리는 주입받은 객체를 그냥 쓰면 됨]
한 줄 요약
스프링은 실행 초기에 메타데이터를 싹 모은 다음,
실행 시점에 리플렉션을 이용해 필요한 의존성을 자동으로 주입(DI)해준다.
개발자는 어디서 어떻게 객체가 만들어졌는지 신경 안 쓰고 쓰기만 하면 된다.
덧붙이면 더 좋은 것
빈을 만들고 관리하는 단계는 스프링에서 이렇게 부른다:
Bean Definition 생성 (메타데이터 만들기)
Bean Instantiation (진짜 객체 생성하기)
Dependency Injection (필요한 의존성 주입)
Initialization (초기화)
Usage (서비스 사용)
그리고 리플렉션이 실제 어디 쓰이냐면:
@Autowired
필드에 값을 주입할 때@Value("${}")
이런거 프로퍼티 주입할 때@Transactional
같은 AOP 프록시 생성할 때@RequestMapping
같은 URL 매핑할 때
전부 리플렉션 기반이다.
비유
스프링은 애플리케이션 전체를 "클래스 설명서(메타정보) 컬렉션"으로 만들고,
실행 중에는 "필요할 때 설명서 보고 물건 조립하듯" 객체를 만들고 연결하는 공장이다.
추가 심화로 이어가자면
- BeanDefinition 객체 안에 실제로 뭐가 저장되는지 (진짜 실습 가능)
- 리플렉션 없이 DI하는 방법 (예: CGLIB 프록시, ASM 코드 생성)
'Spring' 카테고리의 다른 글
리플렉션 2트 (1) | 2025.04.28 |
---|---|
시큐리티 요청 흐름 with GPT (4) | 2024.12.25 |
빈약한 도메인 모델 vs 풍성한 도메인 모델 (0) | 2024.12.19 |
ServletResponse.isComitted(), FilterChain (with GPT) (2) | 2024.12.19 |
(지피티 선생님의) 람다와 일급 객체, FP 특강 (0) | 2024.12.12 |