[스프링 핵심원리] - 3.스프링 컨테이너와 스프링 빈 (1)

Chooooo·2022년 10월 6일
0
post-thumbnail

이 글은 강의 : 김영한님의 - "스프링 핵심원리 - 기본편"을 듣고 정리한 내용입니다. 😁😁


스프링 컨테이너 생성

ApplicationContext = 스프링 컨테이너
- 스프링 컨테이너 생성 방법

  1. XML 기반으로 생성
  2. 어노테이션 기반의 자바 설정 클래스로 생성
  • AppConfig를 사용한 방식
// 스프링 컨테이너 생성
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
  • ApplicationContext는 인터페이스
  • AnnotationConfigApplicationContext 클래스는 ApplicationContext의 구현체

(참고) 스프링 컨테이너는 1) BeanFactory, 2) ApplicationContext 로 구분된다.
BeanFactory를 직접 사용하는 경우는 거의 없으므로 일반적으로 ApplicationContext를 스프링 컨테이라 한다. (자세한건 뒤에서 설명)

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

스프링 컨테이너 생성

new AnnotationConfigApplicationContext(AppConfig.class)
스프링 컨테이너를 생성할 때는 구성 정보를 파라미터 값으로 넘겨주어야 한다.
(여기서 AppConfig.class가 구성 정보!)

스프링 빈 등록

스프링 컨테이너는 파라미터로 넘어온 설정 클래스 정보를 사용해 스프링 빈을 등록한다.

  • 스프링 빈 이름
    • 메서드 이름 사용(디폴트)
    • 직접 부여
      @Bean(name = "memberService2")

(주의) 빈 이름은 항상 다른 이름을 부여해야 한다! 같은 이름을 부여하면 다른 빈이 무시되거나 기존 빈을 덮어쓰는 등 설정에 따라 오류가 발생한다.

스프링 빈 의존관계 설정 - 준비

스프링 빈 의존관계 설정 - 완료

스프링 컨테이너는 설정 정보를 참고해서 의존관계를 주입(DI)한다.
(단순히 자바 코드를 호출하는 것 같지만 차이가 있다. 뒤에 싱글톤 컨테이너에서 설명!)

(참고)
스프링은 빈을 생성하고, 의존관계를 주입하는 단계가 나누어져 있다. 그런데 이렇게 자바 코드로 스프링 빈을 등록하면 생성자를 호출하면서 의존관계 주입도 한번에 처리된다. 여기서는 이해를 돕기 위해 개념적으로 나누어 설명했다. 자세한 내용은 의존관계 자동 주입에서 다시 설명하겠다.


컨테이너에 등록된 모든 빈 조회

스프링 컨테이너에 위에서 등록한 스프링 빈들이 잘 등록되었는지 확인해본다.

ApplicationContextInfoTest

package hello.core.beanfind;

import hello.core.AppConfig;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

class ApplicationContextInfoTest {

    AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
    
    @Test
    @DisplayName("모든 빈 출력하기")
    void findAllBean() {
        // 스프링 컨테이너에 등록된 모든 빈의 이름 조회
        String[] beanDefinitionNames = ac.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            // 빈 이름(key)로 빈(value) 얻기
            Object bean = ac.getBean(beanDefinitionName);
            System.out.println("bean = " + beanDefinitionName + " object = " + bean);
        }
    }
    @Test
    @DisplayName("애플리케이션 빈 출력하기")
    void findApplicationBean() {
        // 스프링 컨테이너에 등록된 모든 빈의 이름 조회
        String[] beanDefinitionNames = ac.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            // 빈에 대한 메타데이터 정보
            BeanDefinition beanDefinition = ac.getBeanDefinition(beanDefinitionName);

            // ROLE_APPLICATION : 일반적으로 사용자가 정의한 빈
            // ROLE_INFRASTRUCTURE : 스프링이 내부에서 사용하는 빈
            if (beanDefinition.getRole() == BeanDefinition.ROLE_APPLICATION) {
                // 빈 이름(key)로 빈(value) 얻기
                Object bean = ac.getBean(beanDefinitionName);
                System.out.println("bean = " + beanDefinitionName + " object = " + bean);
            }
        }
    }
}

모든 빈 출력하기

스프링에 등록된 모든 빈 출력
- ac.getbeanDefinitionNames() : 스프링에 등록된 모든 빈 이름을 조회
- ac.getBean(빈이름) : 빈 이름으로 빈 객체(인스턴스) 조회

애플리케이션 빈 출력하기

스프링 내부에서 사용하는 빈은 제외하고 내가 등록한 빈만 출력한다.
- ac.getBeanDefinition(빈 이름) : 빈 이름으로 빈의 메타데이터 조회
- beanDefinition.getRole() : 빈 구분하기
ROLE_APPLICATION : 일반적으로 사용자가 정의한 빈
ROLE_INFRASTRUCTURE : 스프링이 내부에서 사용하는 빈

profile
back-end, 지속 성장 가능한 개발자를 향하여

0개의 댓글