DI(Dependency Injection)

박채은·2022년 12월 11일
0

Spring

목록 보기
7/35
post-custom-banner

이전에 정리한 DI 글 참고

Spring 컨테이너

  • 스프링 프레임워크의 핵심 컴포넌트

    • 컨테이너 = 내부에 또 다른 컴포넌트를 가지고 있는 어떤 컴포넌트
    • 스프링 컨테이너에서 내부에 있는 또 다른 컴포넌트는 이다.
  • 빈의 생명주기를 관리

    • 빈의 생성, 관리, 제거를 담당
    • 컨테이너는 개발자가 정의한 Bean을 객체로 만들어 관리하고, 개발자가 필요로 할 때 제공한다.
  • ApplicationContext = 스프링 컨테이너

    • ApplicationContext는 인터페이스로 구현되어 있다.
  • 컨테이너는 XML애너테이션 기반의 자바 설정 클래스로 만들 수 있다.

  • 컨테이너는 빈을 생성하고 객체를 서로 연결해준다.

  • 컨테이너는 객체의 의존성을 확인해서, 의존성 주입을 해준다.

  • 스프링 컨테이너가 애플리케이션 시작하기 전에, 빈을 전부 다 불러와서 로드해온다.

  • BeanFactory, ApplicationContext 두 개의 컨테이너로 DI가 이루어진 빈들을 제어하고 관리함


Spring 컨테이너를 사용하는 이유

  • new 연산자를 사용하면, 객체 간의 의존성, 결합도가 높아진다.

  • 낮은 의존성/결합도높은 캡슐화가 객체 지향 프로그래밍의 핵심이므로 객체 간의 의존성을 낮추기 위해 Spring 컨테이너를 사용한다.

  • Spring 컨테이너를 사용함으로써, 구현 클래스에 있는 의존을 제거하고 인터페이스에만 의존하도록 설계할 수 있다.

Spring 컨테이너 생성

// Spring Container 생성(인스턴스화)
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(DependencyConfig.class);
  • 스프링 컨테이너는 Configuration Metadata를 사용함

  • 스프링 컨테이너는 인자로 넘어온 설정 클래스를 사용해서 빈을 등록한다.

    • 설정 클래스에 있는 구성 정보들을 통해서 필요한 객체(빈)를 생성한다.
  • Configuration Metadata설정 클래스가 결합되어, ApplicationContext가 생성 및 초기화된다.

Configuration Metadata(설정 메타데이터): 스프링에서 지원되는 모든 구성 속성의 세부 정보를 제공하는 메타데이터 파일
설정 클래스 = @Configuration 애너테이션을 사용한 클래스


Spring 컨테이너의 종류

1. BeanFactory

  • 스프링 컨테이너의 최상위 인터페이스
  • 설정 파일에 등록된 Bean 객체를 생성하고 관리하는 컨테이너
    • 빈을 등록, 생성, 조회, 돌려주는 등의 관리를 해줌
  • @Bean이 붙은 메서드명을 빈의 이름으로 설정하고, 해당 메서드의 반환값을 스프링 컨테이너에 등록해준다.
  • getBean()을 통해, 빈을 인스턴스화 한다.

2. ApplicationContext

  • BeanFactory의 기능을 상속받아 제공한다.
  • 빈을 등록, 생성, 조회하는 등의 기능은 BeanFactory가 해주고, 그 외의 부가적인 기능을 제공한다.

  • 스프링 컨테이너가 관리하는 객체, 스프링 컨테이너에 등록된 객체
  • @Bean이 추가된 메소드를 모두 호출해서 반환된 객체를 스프링 컨테이너에 스프링 빈으로 등록한다.
  • 빈은 클래스의 등록 정보, getter, setter 메서드를 포함한다.
  • 빈을 생성할 때는 BeanDefinition(빈의 메타데이터)와 해당 객체의 클래스 둘 다 필요하다.(BeanDefinition만 있으면 안된다!)

Java Bean vs Spring Bean

  • Spring에서의 빈과 Java에서의 빈은 다르다!
  • 일반적으로 불리는 빈은 Spring의 빈이다.
  • Java의 Bean: 단순하게 getter, setter만 가지고 있는 클래스

BeanDefinition

  • Bean의 설정 메타데이터 = 빈의 정보들
  • @Bean 당 한 개씩 메타 정보가 생성됨
  • Spring ContainerBeanDefinition라는 추상화를 통해서 Spring Bean을 생성한다.
  • BeanDefinition의 속성에 따라, Bean을 정의 및 생성하며, 어떻게 관리할지 결정한다.
  • BeanDefinition은 설정 정보(클래스, xml 또는 다른 파일)로 추상화되어 만들어진다.
    • BeanDefinition은 추상화되어 있기 때문에 어떤 파일 형식으로도 받을 수 있다는 것

중간 정리

ApplicationContext applicationContext = new AnnotationConfigApplicationContext(DependencyConfig.class);
  • AC(ApplicationContext) = 인터페이스 = 스프링 컨테이너
  • ACAC(AnnotationConfigApplicationContext) = AC의 구현체
  • DependencyConfig 클래스 = @Configuration 애너테이션을 사용한 클래스
    • 해당 클래스 내부에 Bean에 대한 정보들(@Bean)이 존재할 것이다.

1) DependencyConfig 클래스를 인자로 주어, Spring 컨테이너를 생성한다.
2) 그때 내부적으로는, DependencyConfig 클래스의 정보를 바탕으로 BeanDefinition 인터페이스의 구현체(AnnotatedGenericBeanDefinition)를 만들게 된다.
3) BeanDefinition 인터페이스의 구현체에서 Bean 메타정보를 가지고 Spring 컨테이너에서 Bean을 생성한다.


빈 스코프

  • 빈이 존재할 수 있는 범위
  • 스프링 컨테이너에서 빈 스코프의 기본값은 싱글톤 스코프이다.

싱글톤 스코프(싱글톤 패턴)

  • 클래스의 인스턴스가 딱 1개만 생성되는 것을 보장한다.

    • 하나의 인스턴스를 공유하게 된다.
    • private 생성자를 사용해 외부에서 임의로 new를 사용하지 못하도록 막아야 한다.
    • 싱글톤 스코프의 스프링 빈은 여러 번 호출해도 모두 같은 인스턴스 참조 주소값을 가진다.
  • 스프링 컨테이너의 시작에 생성되고, 스프링 컨테이너가 종료될 때 소멸된다.

  • 단일 인스턴스는 싱글톤 빈의 캐시에 저장된다.

싱글톤 스코프의 장점

  • 메모리를 낭비하지 않고, 효율성이 높다.

싱글톤 스코프의 단점

  • 멀티쓰레드 환경에서 하나의 인스턴스만을 공유하기 때문에, 예상치 못한 이슈가 발생할 수 있다.
    • 가급적 읽기만 해야한다.
    • 특정 클라이언트가 값을 변경할 수 있으면 안 된다.
    • 해당 객체에 공유 값을 설정하면 안 된다.
  • 싱글톤 빈은 애플리케이션 구동 시 생성되기 때문에, 싱글톤 빈이 많을수록 Application 구동 시간이 증가한다.(초기의 설정 시간 ↑)

싱글톤 컨테이너

이런 싱글톤 스코프(패턴)의 단점을 해결하기 위해서, 싱글톤 컨테이너를 사용한다.

  • 스프링 컨테이너가 싱글톤 컨네이터 역할을 한다.
  • 싱글톤 레지스터리: 싱글톤 객체를 생성하고 관리하는 기능
  • 스프링 컨테이너가 싱글톤 레지스터리 기능을 통해서 객체를 관리하기 때문에 싱글톤 패턴의 단점을 해결할 수 있다.

✅ 주요 핵심

  • 스프링 컨테이너는 @Configuration이 붙은 클래스설정 정보로 사용합니다.
    -> @Configuration이 붙으면, Spring Bean이 있는 클래스로 간주하기 때문에

  • @Bean이 적힌 메서드를 모두 호출해서 반환된 객체를 스프링 컨테이너에 등록합니다.

  • 직접 자바 코드로 설정 및 등록했던 것을 스프링 컨테이너에 객체만 스프링 빈으로 등록해주고 스프링 컨테이너에서 찾아서 사용하도록 변경한 것!

post-custom-banner

0개의 댓글