| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 |
- securitycontextholderfilter
- AWS
- 페이징
- DI
- Spring Container
- 컨테이너
- dockerhub
- JPA
- DLQ
- Spring
- Dead Letter Queue
- redis
- JWT
- 스프링 부트
- 서블릿 컨테이너
- 쿠버네티스
- JPQL
- @ComponentScan
- Web
- mybatis
- CORS
- docker
- docker compose
- Routing Key
- kafka
- MSA
- 지연 로딩
- @Transactional
- Spring Data JPA
- JdbcTemplate
- Today
- Total
look-forest
스프링 컨테이너와 스프링 빈 본문
이번 시간에는 스프링 컨테이너와 빈의 생성 과정, 빈의 조회 과정에 대해 알아본다.
스프링 컨테이너의 생성 과정
Q. 스프링 컨테이너는 빈을 어떤 방식으로 저장하는가?
빈 이름을 key로 빈 객체를 value로 저장
빈 이름은 기본적으로 메소드 이름을 사용
Q. 스프링 빈 생성 과정에 필요한 정보는?
구성 정보 (XML, 자바 설정 클래스 등)
1. 스프링 컨테이너 생성
스프링 컨테이너: ApplicationContext (⊃BeanFactory)

- ApplicationContext는 인터페이스
- AnnotationConfigApplicationContext는 구현체
- 스프링 컨테이너는 XML을 기반으로 만들 수 있고, 애노테이션 기반의 자바 설정 클래스로 만들 수 있다
- 스프링 컨테이너를 생성할 때는 구성 정보를 지정해주어야 한다. (여기서는 AppConfig.class를 구성 정보로 지정)

2. 스프링 빈 등록
스프링 컨테이너는 파라미터로 넘어온 구성 정보를 사용해서 스프링 빈을 등록

- 빈 이름을 key로 빈 객체를 value로 저장한다
- 빈 이름은 기본적으로 메소드 이름을 사용한다
그러나 직접 부여할 수도 있다 @Bean(name="memberService2")
주의: 빈 이름은 항상 다른 이름을 부여해야 한다.
같은 이름을 부여하면, 다른 빈이 무시되거나, 기존 빈을 덮어버리거나 설정에 따라 오류가 발생한다.
3. 스프링 빈 의존관계 설정

- 스프링 컨테이너는 설정 정보를 참고해서 의존관계를 주입(DI)한다
그러나 단순히 자바 코드를 호출하는 게 아니다 (싱글톤 컨테이너 파트에서 자세히)
이처럼 스프링은 빈을 생성하고, 의존관계를 주입하는 단계가 나누어져 있다
Q. 그런데 이렇게 자바 코드로 스프링 빈을 등록하면 생성자를 호출하면서 의존관계 주입도 한 번에 처리된다..?
다음에 좀 더 알아볼 기회를 갖겠다.
스프링 빈 조회
스프링 컨테이너를 생성한 후, 설정(구성) 정보를 참고해서 스프링 빈도 등록하고, 의존관계도 설정했다.
이제 스프링 컨테이너에서 객체(빈)를 조회해보자.
스프링 컨테이너에서 빈을 찾는 기본적인 조회 방법
- applicationContext.getBean(빈 이름, 타입)
- applicationContext.getBean(타입) : 자식 타입까지 모두 조회
- applicationContext.getBean(빈 이름) : 이름만으로 찾을 경우 타입 지정 불가


※ 빈은 역할로 구분할 수 있다 (getRole())
- ROLE_APPLICATION : 일반적으로 사용자가 정의한 빈
- ROLE_INFRASTRUCTURE : 스프링이 내부에서 사용하는 빈
동일한 타입이 둘 이상일 경우
뭘 선택해야 할지 몰라서 에러 발생 → 빈 이름을 지정해서 구체화
특정 타입의 빈을 모두 조회하기
ac.getBeandsOfType(type) → Map으로 반환

부모 타입으로 조회하면, 자식 타입도 함께 조회

스프링 컨테이너 : BeanFactory와 ApplicationContext의 차이
BeanFactory: 컨테이너의 최상위 인터페이스. 빈을 관리하고 조회하는 역할
ApplicationContext: BeanFactory와 여타 인터페이스들을 상속받아,빈 관리기능 + 부가 기능 제공

BeanFactory
- 스프링 컨테이너의 최상위 인터페이스
- 스프링 빈을 관리하고 조회하는 역할: getBean() 등 제공
ApplicationContext
- 빈 관리기능 + 부가 기능 제공
- ApplicatonContext가 제공하는 부가기능

1. 메시지 소스를 활용한 국제화 기능
한국에서 들어오면 한국어로, 영어권에서 들어오면 영어로 출력
2. 환경변수
로컬, 개발, 운영등 환경을 구분해서 처리
3. 애플리케이션 이벤트
이벤트 프로그래밍에 필요한 인터페이스. 이벤트를 발행하고 구독하는 모델을 편리하게 지원
4. 편리한 리소스 조회
파일, 클래스패스, 외부 등에서 리소스를 편리하게 읽어올 수 있도록 추상화
스프링 빈 설정 메타 정보 - BeanDefinition
스프링 컨테이너는 다양한 형식의 설정 정보(자바 코드, XML)를 받아들일 수 있게 유연하게 설계되어 있다
Q. 스프링은 어떻게 이런 다양한 설정 형식을 지원하는 것일까?
스프링은 다양한 형태의 설정 정보를 BeanDefinition으로 추상화해서 사용한다.
스프링 컨테이너는 자바 코드인지, XML인지 몰라도 된다. 오직 BeanDefinition(빈 설정 메타정보)만 알면 된다!

Q. 빈 생성 과정
- @Bean이나 <bean>을 보고 빈 메타정보를 생성(BeanDefinition)*
- 스프링 컨테이너는 이 메타정보를 기반으로 스프링 빈을 생성
※ BeanDefinition 생성 방법을 크게 분류하면
1) 팩토리 역할의 빈을 사용(appConfig), 빈을 생성할 팩토리 메소드 지정(memberService())
2) BeanDefinition를 직접 생성해서 컨테이너에 등록
실제 bean definition을 출력해보면 beanClassName, factoryBean, factoryMethod, scope 등 정보가 담겨있다

참고 자료 & 이미지 출처
스프링 핵심 원리(김영한 님)
'Spring > Spring 핵심 원리' 카테고리의 다른 글
| 컴포넌트 스캔 - 자동 빈 등록 (0) | 2023.04.29 |
|---|---|
| 싱글톤 컨테이너 - 스프링 컨테이너가 제공하는 기능 (0) | 2023.04.29 |
| [예제] SPRING으로 전환하기 (0) | 2023.04.29 |
| IoC/DI 컨테이너 (0) | 2023.04.29 |
| [예제] 스프링 없이 좋은 객체 지향 설계하기 (0) | 2023.04.29 |