본문 바로가기
Java/Spring

스프링 빈과 스프링 컨테이너

by yongckim 2022. 9. 4.
728x90
반응형

스프링 빈과 스프링 컨테이너

스프링 컨테이너는 스프링에서 자바 객체들을 관리하는 공간을 의미합니다.

스프링에서는 자바 객체를 빈(Bean)이라고 부르며 스프링 컨테이너는 빈의 생명주기(생성 → 설정 → 초기화 → 소멸)를 관리하게 됩니다.

스프링 컨테이너를 사용하면 스프링 컨테이너가 빈을 관리하기 때문에 개발자가 직접 객체를 관리하지 않아도 됩니다.

스프링 컨테이너의 종류

스프링 컨테이너는 다음과 같이 두 종류로 나누어집니다.

  • BeanFactory

스프링 컨테이너의 최상위 인터페이스로, 스프링 빈을 관리하고 조회하는 역할을 담당합니다.

예를 들어, 등록된 Bean을 가지고 있는 getBean() 메서드를 제공하고 있습니다.

  • ApplicationContext

ApplicationContext는 BeanFactory를 구현하고 다음과 같은 부가적인 기능을 제공합니다.

  • 메시지 소스를 활용한 국제화 기능 (MessageSource)
    • 국가에 따라 제공하는 언어를 다르게 할 수 있게 해줍니다.(한국에서는 한글, 미국에서는 영어 등)
  • 환경 변수 (EnvironmentCapable)
    • 로컬 환경, 개발 서버 환경, 운영 서버 환경들에 대해 다른 환경변수를 제공할 수 있습니다.
  • 애플리케이션 이벤트 (ApplicationEventPublisher)
    • 이벤트를 발행하고 구독하는 모델을 편리하게 설정할 수 있게 해줍니다.
  • 편리한 리소스 조회 (ResourceLoader)
    • 파일, 클래스 패스, 외부 등에서 리소스를 편리하게 조회합니다.

실제로 BeanFactory를 사용할 일은 거의 없고 부가기능이 포함된 ApplicationContext를 많이 사용하게 됩니다.

스프링 컨테이너 생성

스프링 컨테이너는 BeanFactory 또는 ApplicationContext를 사용하며, 주로 부가기능이 포함된 ApplicationContext라는 인터페이스를 사용한다는 것을 알았습니다.

ApplicationContext가 인터페이스라면 이를 구현하는 구현 클래스가 필요한데 대표적으로 다음과 같은 구현클래스가 존재합니다.

  • AnnotationConfigApplicationContext

자바 코드를 기반으로 된 설정 정보를 사용하는 클래스입니다.

파라미터로 클래스 파일을 전달합니다.

ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
  • GenericXmlApplicationContext

XML 파일 기반의 설정 정보를 사용하는 클래스입니다.

파라미터로 XML 파일을 전달합니다.

ApplicationContext ac = new GenericXmlApplicationContext(AppConfig.xml);

스프링 컨테이너의 생성 과정

  1. 설정 정보를 인수로 넘겨 스프링 컨테이너를 생성합니다.

2. 스프링 컨테이너는 인수로 전달받은 설정 정보를 읽어 빈 저장소에 저장합니다.

 

원래는 스프링은 빈을 생성하고, 의존관계를 주입하는 단계가 나뉘어져 있습니다. 단, 지금 처럼 자바코드를 사용하는 경우 의존관계 주입도 한번에 처리됩니다.

스프링 빈 조회하기

스프링 빈을 조회하기 위해서는 생성한 스프링 컨테이너(BeanFactory, ApplicationContext)에 특정 메서드를 호출해야 합니다.

  • 스프링 빈 단일조회

getBean() 메서드를 사용하면 스프링 빈의 단일조회를 할 수 있습니다.

// ac.getBean(타입)
// ac.getBean(빈이름, 타입)
BeanA bean = ac.getBean(BeanA.class);
BeanA bean = ac.getBean("beanA", BeanA.class);

만약 조회대상 빈이 없으면 NoSuchBeanDefinitionException이 발생합니다.

  • 스프링 빈 여러개 조회

getBeansOfType() 메서드를 사용하면 여러개의 빈을 동시에 조회할 수 있습니다.

이를 통해 같은 타입으로 여러개 등록되었더라도 이름이 다르다면 구분해서 특정 빈을 가져올 수있습니다.

// ac.getBeansOfType()
Map<String, BeanA> bean = ac.getBeansOfType(BeanA.class);

스프링 빈 조회시 상속관계

스프링 빈을 조회할때, 부모 타입으로 조회되면 자식 타입도 함께 조회됩니다.

예를 들어 다음과 같이 빈이 등록되어 있는 상태라고 가정해봅시다.

Map<String, PaymentService> bean = ac.getBeansOfType(PaymentService.class);

여기서 위와 같이 스프링 빈을 여러개 조회하는 getBeansOfType() 메서드를 호출하면 PaymentService를 구현하는 naverPaymentService와 kakaoPaymentService도 같이 조회하게 됩니다.

부모 타입으로 조회하는 경우 자식 타입도 다 조회되기 때문에 Object 타입으로 조회할 경우 등록된 모든 Bean이 조회됩니다.

BeanDefinition

스프링은 자바코드로도 빈을 등록할 수 있고 XML로도 빈을 등록할 수 있습니다.

이게 가능한 이유는 설정 정보를 읽어 BeanDefinition으로 만들기 때문에 가능합니다.

BeanDefinition에 들어가는 정보는 다음과 같습니다.

  • BeanClassName → 생성할 빈의 클래스 명(자바 설정 처럼 팩토리 역할의 빈을 사용하면 없음)
  • factoryBeanName → 팩토리 역할의 빈을 사용할 경우 이름 (설정 정보 클래스)
  • factoryMethodName → 빈을 생성할 팩토리 메서드의 이름 (빈을 등록할때 사용하는 메서드 이름)
  • Scope → 스프링의 빈 스코프로, 기본적으로 싱글톤으로 동작합니다.
  • lazyInit → 스프링 컨테이너를 생성할 때 빈을 생성하는 것이 아니라, 실제 빈을 사용할 때 까지 최대한 생성을 지연처리 하는지 여부
  • InitMethodName → 빈을 생성하고 의존관계를 설정한 후 호출되는 초기화 메서드 이름
  • DestroyMethodName → 빈의 생명주기가 끝나서 제거하기 직전에 호출되는 메서드 명
  • Constructor argments, Properties : 의존 관계 주입에서 사용되며, 자바 설정 처럼 팩토리 역할을 하는 빈(설정 정보 클래스와 같이)을 사용하면 없습니다.

정리

  • 스프링에서는 자바 객체를 빈(Bean)이라고 부릅니다.
  • 스프링에서 빈들을 관리하는 객체를 스프링 컨테이너라고 부릅니다.
  • 스프링 컨테이너는 BeanFactory, ApplicationContext가 있으며 주로 부가기능이 추가된 ApplicationContext를 사용합니다.
  • 스프링 컨테이너는 설정 정보를 인수로 넘겨 생성합니다.
  • 스프링 컨테이너는 자바 코드, XML와 같이 다양한 방법으로 설정 정보를 스프링 컨테이너에 전달할 수 있습니다.
  • 스프링 빈 조회시 부모 타입으로 조회하면 자식 타입까지 조회됩니다.
  • 스프링은 설정 정보를 읽어 BeanDefinition으로 만들어 관리합니다.

참고 자료

https://velog.io/@tank3a/스프링-컨테이너와-스프링-빈

https://www.inflearn.com/course/스프링-핵심-원리-기본편

https://beststar-1.tistory.com/39

반응형