4. 스프링 컨테이너와 스프링 빈
핵심 정리
핵심 요약:
스프링 컨테이너 생성:
- 스프링 애플리케이션의 핵심인
ApplicationContext
를 생성하며, 스프링 빈의 관리 및 의존성 주입을 담당하는 역할을 한다. 주로 애노테이션 기반 또는 XML 기반 설정으로 구성된다.
스프링 컨테이너 생성 코드:
java
- 스프링 애플리케이션의 핵심인
코드 복사
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
2. **스프링 빈 등록 및 조회**:
- 스프링 컨테이너는 설정 정보(예: `AppConfig.class`)를 기반으로 **스프링 빈을 등록**하고, 의존성을 주입(DI)한다.
- 빈의 이름은 기본적으로 메서드 이름을 사용하지만, 직접 지정할 수도 있다.
**스프링 빈 등록 예시**:
java코드 복사@Bean(name="memberService2")
public MemberService memberService() {
return new MemberServiceImpl(memberRepository());
}
3. **상속 관계에서 스프링 빈 조회**:
- 부모 타입으로 빈을 조회하면, 자식 타입의 빈도 함께 조회할 수 있다. `Object` 타입으로 조회하면 모든 스프링 빈을 조회할 수 있다.
4. **BeanFactory와 ApplicationContext**:
- **`BeanFactory`**는 스프링 컨테이너의 최상위 인터페이스로, 빈의 관리 및 조회 기능을 제공한다.
- **`ApplicationContext`**는 `BeanFactory`를 상속받아, 빈 관리 외에도 국제화, 이벤트 발행 등 다양한 부가 기능을 제공한다.
**`ApplicationContext`와 `BeanFactory`의 차이**:
- `ApplicationContext`는 `BeanFactory`의 기본 기능에 더해 국제화 지원, 애플리케이션 이벤트, 환경 변수 관리 등의 부가 기능을 제공한다.
5. **스프링 빈 설정 메타 정보 - BeanDefinition**:
- 스프링은 XML 또는 애노테이션 기반 설정 파일을 통해 **`BeanDefinition`**을 생성하고, 이를 통해 스프링 빈을 관리한다.
- **`BeanDefinition`**은 빈의 설정 메타 정보를 포함하고 있으며, 스프링 컨테이너는 이 정보를 기반으로 빈을 생성하고 의존성을 주입한다.
### 핵심 키워드 설명:
1. **ApplicationContext**:
- 스프링 컨테이너의 구현체로, 빈의 생성, 관리, 조회를 담당하며, 국제화, 이벤트 발행 등 다양한 기능을 제공한다.
2. **BeanFactory**:
- 스프링 컨테이너의 최상위 인터페이스로, 빈의 생명주기와 의존성 주입을 관리하는 역할을 한다. `ApplicationContext`가 `BeanFactory`를 확장하여 더 많은 기능을 제공한다.
3. **스프링 빈**:
- 스프링 컨테이너에 의해 관리되는 객체로, 의존성 주입 및 생명주기 관리가 이루어진다. 빈의 이름은 기본적으로 메서드 이름을 따르며, 수동으로 지정할 수도 있다.
4. **BeanDefinition**:
- 스프링 컨테이너가 빈을 생성하고 의존성을 주입하기 위한 메타 정보로, XML 설정이나 자바 기반 설정을 바탕으로 스프링 빈의 생성을 추상화한다.
## 스프링 컨테이너 생성
```java
//스프링 컨테이너 생성
ApplicationContext applicationContext = new
AnnotationConfigApplicationContext(AppConfig.class); // `ApplicationContext` 인터페이스의 구현체
ApplicationContext
= 스프링 컨테이너- 작성 방식
- XML 기반
- 애노테이션 기반 자바 설정 클래스
- 작성 방식
스프링 컨테이너 생성 과정
- 스프링 컨테이너 생성
new AnnotationConfigApplicationContext(AppConfig.class)
= 스프링 컨테이너를 생성할 때 구성 정보(AppConfig.class)를 지정
- 스프링 빈 등록
- 스프링 컨테이너는 파라미터로 넘어온 설정 클래스 정보를 사용해서 스프링 빈을 등록
빈 이름
- 메서드 이름 사용
- 직접 부여 가능
@Bean(name="memberService2")
- 주의: 빈 이름은 항상 다른 이름을 부여해야 한다. 같은 이름을 부여하면, 다른 빈이 무시되거나, 기존 빈을 덮어버리거나 설정에 따라 오류가 발생한다.
- 스프링 빈 의존관계 설정 - 준비
- 스프링 빈 의존관계 설정 - 완료
- 스프링 컨테이너는 설정 정보를 참고해서 의존관계를 주입(DI)
참고 : 스프링은 빈을 생성하고, 의존관계를 주입하는 단계가 나누어져 있다. 그런데 이렇게 자바 코드로 스프링 빈을 등록하면 생성자를 호출하면서 의존관계 주입도 한번에 처리된다.
스프링 빈 조회 - 상속 관계
- 부모 타입으로 조회하면, 자식 타입도 함께 조회한다.
- 모든 자바 객체의 최고 부모인
Object
타입으로 조회하면, 모든 스프링 빈을 조회
BeanFactory와 ApplicationContext
BeanFactory
- 스프링 컨테이너의 최상위 인터페이스다.
- 스프링 빈을 관리하고 조회하는 역할을 담당한다.
getBean()
을 제공한다.
ApplicationContext
BeanFactory
기능을 모두 상속 받아서 제공- 빈을 관리하고 조회하는 기능 + 수 많은 부가 기능 제공
ApplicatonContext가 제공하는 부가기능
- 메시지소스를 활용한 국제화 기능
- 예를 들어서 한국에서 들어오면 한국어로, 영어권에서 들어오면 영어로 출력
- 환경변수
- 로컬, 개발, 운영등을 구분해서 처리
- 애플리케이션 이벤트
- 이벤트를 발행하고 구독하는 모델을 편리하게 지원
- 편리한 리소스 조회
- 파일, 클래스패스, 외부 등에서 리소스를 편리하게 조회
정리
ApplicationContext
는BeanFactory
의 기능을 상속 받는다.ApplicationContext
는 빈 관리기능 + 편리한 부가 기능을 제공한다.BeanFactory
를 직접 사용할 일은 거의 없다. 부가기능이 포함된ApplicationContext
를 사용한다.BeanFactory
나ApplicationContext
를 스프링 컨테이너라 한다.
애노테이션 기반 자바 코드 설정 사용
new AnnotationConfigApplicationContext(AppConfig.class)
AnnotationConfigApplicationContext
클래스를 사용하면서 자바 코드로 된 설정 정보를 넘긴다.XML 설정 사용
GenericXmlApplicationContext
를 사용하면서xml
설정 파일을 넘기면 된다.
XmlAppConfig 사용 자바 코드
package hello.core.xml;
import hello.core.member.MemberService;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;
import static org.assertj.core.api.Assertions.*;
public class XmlAppContext {
@Test
void xmlAppContext() {
ApplicationContext ac = new
GenericXmlApplicationContext("appConfig.xml");
MemberService memberService = ac.getBean("memberService",
MemberService.class);
assertThat(memberService).isInstanceOf(MemberService.class);
}
}
xml 기반의 스프링 빈 설정 정보
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://
www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="memberService" class="hello.core.member.MemberServiceImpl">
<constructor-arg name="memberRepository" ref="memberRepository" />
</bean>
<bean id="memberRepository"
class="hello.core.member.MemoryMemberRepository" />
<bean id="orderService" class="hello.core.order.OrderServiceImpl">
<constructor-arg name="memberRepository" ref="memberRepository" />
<constructor-arg name="discountPolicy" ref="discountPolicy" />
</bean>
<bean id="discountPolicy" class="hello.core.discount.RateDiscountPolicy" />
</beans>
스프링 빈 설정 메타 정보 - BeanDefinition
- 역할과 구현을 개념적으로 나눈 것
- XML 또는 자바 코드를 BeanDefinition을 만들면 된다.
- 스프링 컨테이너는 자바 코드인지, XML인지 몰라도 된다. 오직 BeanDefinition만 알면 된다.
BeanDefinition
을 빈 설정 메타정보라 한다.@Bean
,<bean>
당 각각 하나씩 메타 정보가 생성된다.
- 스프링 컨테이너는 이 메타정보를 기반으로 스프링 빈을 생성한다.
AnnotationConfigApplicationContext
는AnnotatedBeanDefinitionReader
를 사용해서AppConfig.class
를 읽고BeanDefinition
을 생성한다.GenericXmlApplicationContext
는XmlBeanDefinitionReader
를 사용해서appConfig.xml
설정 정보를 읽고BeanDefinition
을 생성한다.- 새로운 형식의 설정 정보가 추가되면,
XxxBeanDefinitionReader
를 만들어서BeanDefinition
을 생성하면 된다.
BeanDefinition 살펴보기
BeanDefinition 정보
- BeanClassName: 생성할 빈의 클래스 명(자바 설정 처럼 팩토리 역할의 빈을 사용하면 없음)
- factoryBeanName: 팩토리 역할의 빈을 사용할 경우 이름, 예) appConfig
- factoryMethodName: 빈을 생성할 팩토리 메서드 지정, 예) memberService
- Scope: 싱글톤(기본값)
- lazyInit: 스프링 컨테이너를 생성할 때 빈을 생성하는 것이 아니라, 실제 빈을 사용할 때 까지 최대한 생성을 지연처리 하는지 여부
- InitMethodName: 빈을 생성하고, 의존관계를 적용한 뒤에 호출되는 초기화 메서드 명
- DestroyMethodName: 빈의 생명주기가 끝나서 제거하기 직전에 호출되는 메서드 명
- Constructor arguments, Properties: 의존관계 주입에서 사용한다. (자바 설정 처럼 팩토리 역할의 빈을 사용하면 없음)
정리
BeanDefinition
을 직접 생성해서 스프링 컨테이너에 등록할 수도 있다. 하지만 실무에서BeanDefinition
을 직접 정의하거나 사용할 일은 거의 없다.BeanDefinition
에 대해서는 너무 깊이 있게 이해하기 보다는, 스프링이 다양한 형태의 설정 정보를BeanDefinition
으로 추상화해서 사용하는 것 정도만 이해하면 된다.- 가끔 스프링 코드나 스프링 관련 오픈 소스의 코드를 볼 때,
BeanDefinition
이라는 것이 보일 때가 있다. 이때 이러한 메커니즘을 떠올리면 된다.
Reference
- 인프런 김영한 강의 - 스프링 핵심 원리 - 기본편
'Web_Backend > 스프링 핵심 원리 - 기본편' 카테고리의 다른 글
6. 컴포넌트 스캔 (0) | 2024.09.09 |
---|---|
5. 싱글톤 컨테이너 (0) | 2024.08.15 |
3. 스프링 핵심 원리 이해2 - 객체 지향 원리 적용 (0) | 2024.08.15 |
2. 스프링 핵심 원리 이해 1 - 예제 만들기 (0) | 2024.08.01 |
1. 객체 지향 설계와 스프링 (0) | 2024.07.31 |