스프링의 핵심개념 중 하나인 DI를 공부한다!
DI
스프링 컨테이너
스프링 컨테이너는 스프링 프레임워크의 핵심 컴포넌트
스프링 컨테이너?
Bean 생성, 관리, 제거 등의 역할을 담당
컨테이너를 사용하는 이유?
객체간의 의존성을 낮추기 위해서
-> 구현 클래스에 있는 의존을 제거하고 인터페이스에만 의존하도록 설계
Spring Container 생성
```java ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
ApplicationContext 인터페이스 구현체 확인법
Windows에서 Ctrn + N → 클래스에서 ApplicationContext로 검색
컨테이너의 종류
BeanFactory
스프링 컨테이너의 최상위 인터페이스
빈을 등록, 생성, 조회, 돌려줌 -> 빈을 관리하는 역할
```java
- getBean(): 빈을 인스턴스화
- @Bean: 스프링 빈의 이름으로 사용해 빈 등록
ApplicationContext
BeanFactory의 기능을 상속받아 제공
```java
- MessageSource: 메세지 다국화를 위한 인터페이스
- EnvironmentCapable: 개발, 운영 등 환경변수 등으로 나눠 처리 애플리케이션 구동 시 필요한 정보들을 관리하기 위한 인터페이스
- ApplicationEventPublisher: 이벤트 관련 기능을 제공하는 인터페이스
- ResourceLoader: 파일, 클래스 패스, 외부 등 리소스를 편리하게 조회
컨테이너 인스턴스화
다양한 외부 리소스로부터 구성 메타데이터를 로드할 수 있도록 하는 리소스 문자열
- Annotation ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); - XML ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");
빈
스프링 컨테이너에 의해 관리되는 재사용 소프트웨어 컴포넌트
빈?
빈(bean)은 인스턴스화된 객체
@Bean이 적힌 메서드를 모두 호출해서 반환된 객체를 스프링 컨테이너에 등록
빈 접근방법
- create and configure beans ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml"); - retrieve configured instance PetStoreService service = context.getBean("cmarket", cmarketService.class); - use configured instance List<String> userList = service.getUsernameList();
BeanDefinition (빈 설정 메타정보)
속성에 따라 컨테이너가 Bean을 어떻게 생성하고 관리할지 결정
@Bean
or<bean>
당 각 1개씩 메타 정보가 생성
빈 스코프
레시피
bean definition에 의해 정의된 클래스의 실제 인스턴스를 만들기 위한 레시피를 만듦
-> 빈이 존재할 수 있는 범위를 의미
싱글톤(singleton) 스코프
클래스의 인스턴스가 딱 1개만 생성되는 것을 보장하는디자인 패턴
```java 컨테이너의 시작과 함께 생성되어 컨테이너가 종료될 때 까지 유지 컨테이너 종료시 소멸 메서드도 자동으로 실행
싱글톤 패턴의 문제점
```java
- 구현하는 코드가 많음
- 클라이언트가 구체 클래스에 의존
- 유연성이 떨어짐
싱글톤 컨테이너로 문제 해결!
```java
- 스프링 컨테이너는 싱글톤 컨테이너 역할을 함
- 싱글톤 레지스트리: 싱글톤 객체로 생성하고 관리
싱글톤 방식의 주의점
-> 여러 클라이언트가 하나의 객체 인스턴스를 공유하기 때문에 싱글톤 객체는 무상태로 설계
```java
- 특정 클라이언트가 값을 변경할 수 있으면 안됨
- 읽기만 가능해야 됨
- 스프링 빈의 공유 값을 설정하면 장애가 발생할 수 밖에 없음
Java 기반 컨테이너(Container) 설정
@Configuration와 @Bean이 가장 중요한 애너테이션
Spring 컨테이너에서 관리할 새 객체를 인스턴스화, 구성 및 초기화한다는 것을 표기할 때 사용
@Bean 애너테이션을 사용하기
메서드-레벨 애너테이션이며,
에서 제공하는 일부 속성을 지원 빈 선언 @Bean 애너테이션을 메서드에 추가해서 Bean으로 정의(선언) 빈의존성 @Bean 애너테이션이 추가된(@Bean-annotated) 메서드 -> 빈을 구축하는데 필요한 의존성을 나타내는데 매개 변수를 사용가능
@Configuration 애너테이션을 사용하기
해당 객체가 bean definitions의 소스임을 나타내는 애너테이션
Component 스캔
설정 정보 없이 자동으로 스프링 빈을 등록