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

gudals-kim·2023년 8월 9일

스프링

목록 보기
2/3

🍃 스프링 컨테이너

**스프링 컨테이너** 는 자바 객체의 생명 주기를 관리하며, 생성된 자바 객체들에게 추가적인 기능을 제공하는 역할이다. 스프링에서는 자바 객체를 **빈(Bean)**이라고 부르며, **IoC**, **DI**와 같은 SOLID원칙을 지키기 위한 기술이 **스프링 컨테이너**에 적용되어 있다.


1. 스프링 컨테이너란?


기존 객체의 생성주기는 개발자가 new 연산자, 인터페이스 호출, 팩토리 호출 방식으로 객체를 생성하고 소멸해야 한다.

하지만 스프링에서는 스프링 컨테이너가 이 역할을 대신 해준다. 즉 IoC(제어 흐름을 외부에서 관리한다.)가 적용되어 있다. 또한 객체(빈)간의 의존 관계를 스프링 컨테이너가 런타임(실행중)에 알아서 만들어 준다.

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


//스프링 컨테이너 생성
ApplicationContext applicationContext =
new AnnotationConfigApplicationContext(AppConfig.class);
  • ApplicationContext를 스프링 컨테이너라 한다.
  • ApplicationContext는 인터페이스 이다.
  • AnnotationConfigApplicationContextApplicationContext 인터페이스의 구현체이다.
  • 스프링 컨테이너는 XML을 기반으로 만들 수 있고, 애노테이션 기반의 자바 설정 클래스로 만들 수 있다.

✔ [생성] 스프링 컨테이너 생성


이미지1

//스프링 컨테이너 생성
ApplicationContext applicationContext =
new AnnotationConfigApplicationContext(AppConfig.class);
  • 스프링 컨테이너를 생성할 때는 구성 정보를 지정해 주어야한다.
  • 위 코드에서는 AppConfig.class가 구성 정보이다.

✔ [등록] 스프링 빈 등록


이미지2

스프링 컨테이너는 구성정보(config.class 정보)를 사용해서 스프링 빈을 등록한다.

스프링 빈 저장소에 key(빈 이름) → value(빈 객체) 로 map과 같은 형태로 저장되어 있다고 생각하면 편하다.

스프링 빈 규칙

  • 빈 이름은 메서드 이름을 사용한다.
  • 빈 이름을 직접 부여할 수 있다.
  • 빈 이름은 항상 다른 이름을 부여 해야 한다.

✔ 스프링 빈 의존 관계 설정


https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdsPa4O%2FbtrDc7tYgrY%2FLUUwC8SJrETxsO8gZpOGBk%2Fimg.png

  • 스프링 컨테이너는 구성 정보를 참고해서 의존관계를 주입한다.
  • 단순히 자바 코드를 호출하는 것과 차이가 있다.(싱글톤 컨테이너)
  • 스프링 빈을 등록하는 순간, 의존 관계 주입도 한번에 처리된다.

✔ [조회] 컨테이너에 등록된 빈 조회


public class ApplicationContextInfoTest {
		 //스프링 컨테이너 생성
    AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
 
    @Test
    @DisplayName("모든 빈 출력하기")
    void findAllBean() {
        String[] beanNames = ac.getBeanDefinitionNames();//스프링에 등록된 모든 빈 이름을 조회
        for (String beanName : beanNames ) {
            Object bean = ac.getBean(beanName);//빈 이름으로 빈 객체(인스턴스)를 조회
            System.out.println("name = " + beanName + "Object =" + bean);
        }
    }
 
    @Test
    @DisplayName("직접 등록한 빈 출력하기")
    void findApplicationBean() {
        String[] beanNames = ac.getBeanDefinitionNames();
        for (String beanName: beanNames ) {

						//getBeanDefinition: Bean에 대한 meta data 정보들을 반환한다
            BeanDefinition beanDefinition = ac.getBeanDefinition(beanName);

						 //사용자가 정의한 빈일 경우에만 if문 수행
            //Role ROLE_APPLICATION: 직접 등록한 애플리케이션 빈
            //Role ROLE_INFRASTRUCTURE: 스프링이 내부에서 사용하는 빈
            if (beanDefinition.getRole() == BeanDefinition.ROLE_APPLICATION){ 
                Object bean = ac.getBean(beanName);
                System.out.println("name = " + beanDefinitionName + "Object =" + bean);
            }
 
        }
    }
 
}

주요 메서드

  • ac.getBeanDefinitionNames() : 스프링에 등록된 모든 빈 이름을 조회한다.
  • ac.getBean() : 빈 이름으로 빈 객체를 조회한다.
  • ac.getBeanDefinition() : Bean에 대한 meta data 정보를 반환한다.
  • ac.getBeansOfType() : 사용하면 해당 타입의 모든 빈을 조회할 수 있다. (return : map)

빈 조회 규칙

  • 부모 타입으로 조회하면 자식 타입도 함께 조회한다.
    • → 모든 자바 객체의 최고 부모인 Object 타입으로 조회하면, 모든 스프링 빈을 조회한다.

💡 실제로 ApplictionContext에서 직접 getBean()을 쓸 일은 별로 없다.
주로 스프링이 자동으로 의존관계를 주입해주기 때문
단, 자동 주입에 대해 쉽게 이해하기 위해서는 한번쯤은 이해해야하며, 순수 java에서 spring container를 사용해야할때 사용된다.

3. 스프링 컨테이너 종류


스프링 컨테이너에는 BeanFactoryApplicationContext가 있습니다.

1. BeanFactory

  • 스프링 컨테이너의 최상위 인터페이스
  • 스프링 빈을 관리하고 조회하는 역할을 담당한다.
  • getBean() 등의 빈 객체와 관련된 메서드를 해당 인터페이스가 제공한다.

2. ApplicationContext

  • BeanFactory 기능을 모두 상속받아서 제공한다.
  • BeanFactory의 모든 기능을 포함하는 것은 물론이고 아래 추가 기능들을 제공한다.
  • 대표적인 추가기능
    • **Environment : 프로파일(Profile)을 설정하고 어떤 것을 사용할지 선택할 수 있게 해주며, 소스 설정 및 프로퍼티 값을 가져오게 해준다.
    • **MessageSource : 메세지 설정 파일을 모아서 각 국가마다 로컬라이징을 함으로써 각 지역에 맞춤 메시지를 제공(메시지에 대한 국제화(i18n)을 제공하는 인터페이스)

💡 BeanFacory는 빈 관리 기능을 제공한다.
ApplicationConext는 빈 관리기능 (BeanFactory)와 더불어 편리한 부가기능을 더 제공한다.
BeanFactory를 직접 사용할 일은 거의 없다. 대부분 부가기능이 포함된 ApplicationContext를 사용한다.
→ 둘 다 스프링 컨테이너라고 부른다.

0개의 댓글