이전에 정리한 DI 글 참고
스프링 프레임워크의 핵심 컴포넌트
빈
이다.빈의 생명주기를 관리
ApplicationContext = 스프링 컨테이너
컨테이너는 XML
과 애너테이션 기반의 자바 설정 클래스
로 만들 수 있다.
컨테이너는 빈을 생성하고 객체를 서로 연결해준다.
컨테이너는 객체의 의존성을 확인해서, 의존성 주입을 해준다.
스프링 컨테이너가 애플리케이션 시작하기 전에, 빈을 전부 다 불러와서 로드해온다.
BeanFactory, ApplicationContext 두 개의 컨테이너로 DI가 이루어진 빈들을 제어하고 관리함
new
연산자를 사용하면, 객체 간의 의존성, 결합도가 높아진다.
낮은 의존성/결합도와 높은 캡슐화가 객체 지향 프로그래밍의 핵심이므로 객체 간의 의존성을 낮추기 위해 Spring 컨테이너를 사용한다.
Spring 컨테이너를 사용함으로써, 구현 클래스에 있는 의존을 제거하고 인터페이스에만 의존하도록 설계할 수 있다.
// Spring Container 생성(인스턴스화)
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(DependencyConfig.class);
스프링 컨테이너는 Configuration Metadata
를 사용함
스프링 컨테이너는 인자로 넘어온 설정 클래스
를 사용해서 빈을 등록한다.
설정 클래스
에 있는 구성 정보들을 통해서 필요한 객체(빈)를 생성한다.Configuration Metadata
와 설정 클래스
가 결합되어, ApplicationContext가 생성 및 초기화된다.
✅ Configuration Metadata(설정 메타데이터): 스프링에서 지원되는 모든 구성 속성의 세부 정보를 제공하는 메타데이터 파일
✅ 설정 클래스 =@Configuration
애너테이션을 사용한 클래스
@Bean
이 붙은 메서드명을 빈의 이름으로 설정하고, 해당 메서드의 반환값을 스프링 컨테이너에 등록해준다.getBean()
을 통해, 빈을 인스턴스화 한다.@Bean
이 추가된 메소드를 모두 호출해서 반환된 객체를 스프링 컨테이너에 스프링 빈으로 등록한다.BeanDefinition
만 있으면 안된다!)✅ Java Bean vs Spring Bean
- Spring에서의 빈과 Java에서의 빈은 다르다!
- 일반적으로 불리는 빈은 Spring의 빈이다.
- Java의 Bean: 단순하게 getter, setter만 가지고 있는 클래스
Bean
의 설정 메타데이터 = 빈의 정보들@Bean
당 한 개씩 메타 정보가 생성됨Spring Container
는 BeanDefinition
라는 추상화를 통해서 Spring Bean을 생성한다.BeanDefinition
의 속성에 따라, Bean을 정의 및 생성하며, 어떻게 관리할지 결정한다.BeanDefinition
은 설정 정보(클래스, xml 또는 다른 파일)로 추상화되어 만들어진다.ApplicationContext applicationContext = new AnnotationConfigApplicationContext(DependencyConfig.class);
@Configuration
애너테이션을 사용한 클래스@Bean
)이 존재할 것이다.1) DependencyConfig 클래스를 인자로 주어, Spring 컨테이너를 생성한다.
2) 그때 내부적으로는, DependencyConfig 클래스의 정보를 바탕으로 BeanDefinition 인터페이스의 구현체(AnnotatedGenericBeanDefinition)를 만들게 된다.
3) BeanDefinition 인터페이스의 구현체에서 Bean 메타정보를 가지고 Spring 컨테이너에서 Bean을 생성한다.
클래스의 인스턴스가 딱 1개만 생성되는 것을 보장한다.
스프링 컨테이너의 시작에 생성되고, 스프링 컨테이너가 종료될 때 소멸된다.
단일 인스턴스는 싱글톤 빈의 캐시에 저장된다.
이런 싱글톤 스코프(패턴)의 단점을 해결하기 위해서, 싱글톤 컨테이너를 사용한다.
스프링 컨테이너는 @Configuration
이 붙은 클래스를 설정 정보로 사용합니다.
-> @Configuration
이 붙으면, Spring Bean이 있는 클래스로 간주하기 때문에
@Bean
이 적힌 메서드를 모두 호출해서 반환된 객체를 스프링 컨테이너에 등록합니다.
직접 자바 코드로 설정 및 등록했던 것을 스프링 컨테이너에 객체만 스프링 빈으로 등록해주고 스프링 컨테이너에서 찾아서 사용하도록 변경한 것!