자바 스프링 핵심개념 (DI)

스프링의 핵심개념 중 하나인 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 스캔

설정 정보 없이 자동으로 스프링 빈을 등록