36DAYS) Spring Framework 핵심개념(1) - DI (Dependency Injection)

nacSeo (낙서)·2022년 12월 8일
0

◉ 학습목표

1.Spirng Container와 Bean의 의미를 이해할 수 있다.
2. 빈 스코프(Bean Scope)와 싱글톤(Singleton)에 대해 이해하고 실습할 수 있다.
  1. DI

⦿ 학습내용

☞ 컨테이너

✔︎ 내부에 또 다른 컴포넌트를 가지고 있는 어떤 컴포넌트를 의미
✔︎ 먼저 객체를 생성하고 객체를 서로 연결
✔︎ 생명주기 전반을 관리
✔︎ 객체의 의존성을 확인해 생성한 뒤 적절한 객체에 의존성 주입
✔︎ 스프링은 스프링 컨테이너를 통해 객체 관리
✔︎ 스프링 컨테이너에서 관리되는 객체를 Bean이라고 함

☞ Spring Container

✔︎ Bean들의 생명주기(Life Cycle)를 관리 (Bean들의 생성, 관리, 제거 등)
✔︎ 관리하기 위해 IoC를 사용
✔︎ BeanFactory, ApplicationContext 두 개의 컨테이너로 DI가 이루어진 빈들을 제어하고 관리

☞ Spring Container 종류

✔︎ BeanFactory

  • 스프링 컨테이너의 최상위 인터페이스
  • 스프링 설정 파일에 등록된 Bean 객체를 생성하고 관리하는 컨테이너

✔︎ ApplicationContext

  • BeanFactory를 상속하여 Bean 객체 관리(부가기능 제공)
  • 부가 기능 (인터페이스)
    - MessageSource : 메시지 다국화 서비스
    - EnvironmentCapable : 개발, 운영, 환경변수 등으로 나눠 처리하고, 애플리케이션 구동 시 필요한 정보들을 관리
    - ApplicationEventPublisher : 이벤트 관련 기능 제공
    - ResourceLoader : 파일, 클래스 패스, 외부 등 리소스를 편리하게 조회

☞ Spring Bean

✔︎ Bean

  • 애플리케이션에서 사용하는 객체
  • 설정 정보와 함께 스프링 컨테이너에 등록된 객체를 의미

✔︎ Java Bean (🆚 Spring Bean)

  • 단순하게 클래스에서 Getter / Setter만 가지고 있는 클래스를 의미

☞ BeanDefinition (Bean 설정 메타정보)

✔︎ 속성에 따라 컨테이너가 Bean을 어떻게 생성하고 관리할 지 결정
✔︎ Spring Container는 BeanDefinition이라는 추상화를 통해 Spring Bean 생성

ApplicationContext ac = new AnnotationConfigApplicationContext(DependencyConfig.class);
// DependencyConfig.class를 파라미터로 ac(ApplicationContext)를 생성하게 되면
// 내부적으로는 DependencyConfig.class 정보를 바탕으로
// BeanDefinition 인터페이스의 구현체 중 하나인 객체를 만듦
// 이를 바탕으로 스프링은 빈을 생성

// AnnotationConfigApplicationContext에 DependencyConfig.class를 넘겨줬을 때
// BeanDefinition의 구현체인 AnnotatedGenericBeanDefinition을 만들게 됨
// 해당 객체에서 Bean 메타정보를 가지고 Spring Container에서 Bean을 생성

☞ Bean Scope (빈 스코프)

✔︎ Bean이 존재할 수 있는 범위를 의미
✔︎ 특정 Bean 정의에서 생성된 개체에 연결할 다양한 의존성 및 구성 값뿐만 아니라, 특정 Bean 정의에서 생성된 개체의 범위도 제어 가능
✔︎ Spring Framework는 6개의 범위를 지원하며, 그 중 4개는 ApplicationContext를 사용하는 경우에만 사용 가능

  • singleton : (Default) 각 Spring 컨테이너에 대한 단일 객체 인스턴스에 대한 단일 bean definition의 범위를 지정
  • prototype : 스프링 컨테이너는 프로토타입 Bean의 생성과 의존관계 주입까지만 관여하고 더는 관리하지 않는 매우 짧은 범위의 스코프
  • request : 웹 요청이 들어오고 나갈 때까지 유지되는 스코프
  • session : 웹 세션이 생성되고 종료될 때까지 유지되는 스코프
  • application : 웹의 서블릿 컨텍스와 같은 범위로 유지되는 스코프
  • websocket : 단일 bean definition 범위를 WebSocket의 라이프사이클까지 확장, Spring ApplicationContext의 컨텍스트에서만 유효

✔︎ Bean은 여러 범위 중 하나에 배치될 수 있도록 정의할 수 있음
✔︎ 구성을 통해 개체의 범위를 선택할 수 있기 때문에 강력하고 유연
✔︎ 사용자 정의 범위도 생성 가능

☞ 싱글톤(Singleton) 스코프

✔︎ 해당 빈의 인스턴스를 오직 하나만 생성해서 사용하는 것을 의미
✔︎ 스프링 컨테이너에서 빈 스코프의 기본값
✔︎ 스프링 컨테이너의 시작과 함께 생성되어서 종료될 때까지 유지
✔︎ 싱글톤 빈의 하나의 공유 인스턴스만 관리
(private 생성자를 통해 외부에서 임의로 new를 사용하지 못하도록 막아야 함)
✔︎ 싱글톤 스코프의 스프링 빈은 여러 번 호출해도 모두 같은 인스턴스 참조 주소값을 가짐

☞ 싱글톤 패턴

✔︎ 클래스의 인스턴스가 딱 1개만 생성되는 것을 보장하는 디자인 패턴
✔︎ 문제점 🚨

  • 코드 많음
  • 의존관계상 클라이언트가 구체 클래스에 의존
  • 지정해서 가져오기 때문에 테스트 어려움
  • private 생성자를 사용하기에 자식 클래스를 만들기 어려움 (유연성 ↓)
  • 속성 공유
    - 멀티 스레드 환경에서 1개의 인스턴스에서 속성값을 공유하기에 예상치 못한 값이 나올 수 있음
  • Application 초기 구동 시 인스턴스 생성
    - 싱글톤 빈이 많을수록 구동 시간 ↑

☞ 싱글톤 컨테이너

✔︎ 객체 인스턴스를 싱글톤으로 관리

  • 스프링 컨테이너는 싱글톤 컨테이너 역할
  • 싱글톤 레지스트리 : 싱글톤 객체를 생성하고 관리하는 기능
  • 싱글톤 패턴의 모든 단점 해결

☞ 싱글톤 방식 주의점

✔︎ 여러 클라이언트가 하나의 객체 인스턴스를 공유하기 때문에 싱글톤 객체는 무상태로 설계되어야 함

  • 특정 클라이언트가 값 변경 ❌
  • 읽기만 가능해야 함
  • 스프링 빈의 공유 값을 설정하면 장애 발생 💥

◉ 느낀 점

☞ 앞서 배운 DI를 바탕으로 스프링 컨테이너와 빈, 빈 스코프 중에서도 싱글톤 스코프에 대해 알아봤다. 솔직히 읽고 실습을 해보아도 100%까진 와닿지 않는 어렵고 심오한 내용이었다. 🤯 외우기보단 이해 위주로 실습과 복습을 반복해야겠다. 😤

◉ 내일의 키워드

・ DI (Dependency Injection)
profile
백엔드 개발자 김창하입니다 🙇‍♂️

0개의 댓글