[Spring] 컨테이너와 빈

Seongho·2023년 1월 27일
2

Spring

목록 보기
5/13

스프링 컨테이너 생성

ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);

여기서 ApplicationContext는 인터페이스인데, 스프링 컨테이너라고 한다.
스프링 컨테이너는 애너테이션 기반의 자바 설정 클래스(AppConfig.class)로 만들 수도 있고, XML 기반으로도 만들 수 있다. XML기반으로는 잘 사용하지 않는다.

스프링 컨테이너를 얘기할 때, BeanFactory와 ApplicationContext로 구분해서 얘기하는데, BeanFactory는 스프링 컨테이너의 최상위 인터페이스로 스프링 빈을 관리하고 조회하는 역할을 담당한다.(getBean() 제공)
ApplicationContext는 BeanFactory를 상속받은 인터페이스인데, 빈을 관리하는 기능 + 편리한 부가 기능을 제공한다. (MessageSource, EnvironmentCapable, ApplicationEventPublisher, ResourceLoader)


그림과 같이 @Configuration으로 지정된 설정 클래스 안에서 @Bean이 붙은 매서드를 찾아 실행하면서 스프링 빈을 등록한다.

스프링 컨테이너 생성과 빈 등록 절차

1. 스프링 컨테이너 생성

2. 스프링 빈 등록


이 때, 빈 이름은 @Bean(name="빈 이름") 이렇게 직접 부여할 수 있지만, 디폴트로는 매서드 이름을 사용한다. 빈 이름은 항상 다른 이름을 부여해야 한다.(중요)

3. 스프링 빈 의존관계 설정


의존관계 자동 주입에 대해서는 나중에 추가하기

스프링 컨테이너에 등록된 빈 조회

ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
//
@Test
@DisplayName("애플리케이션 빈 출력하기")
void findApplicationBean() {
 	String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
 	for (String beanDefinitionName : beanDefinitionNames) {
 		BeanDefinition beanDefinition = applicationContext.getBeanDefinition(beanDefinitionName);
 //
    	//Role ROLE_APPLICATION: 직접 등록한 애플리케이션 빈
 		//Role ROLE_INFRASTRUCTURE: 스프링이 내부에서 사용하는 빈
 		if (beanDefinition.getRole() == BeanDefinition.ROLE_APPLICATION) {
 			Object bean = applicationContext.getBean(beanDefinitionName);
 			System.out.println("name=" + beanDefinitionName + " object=" + bean);
 		}
 	}
 }
  • applicationContext.getBeanDefinitionNames() : 스프링 빈에 등록된 모든 빈 이름을 반환한다.
  • applicationContext.getBeanDefinition(beanDefinitionName) : 빈 이름으로 빈에 대한 정보를 반환한다.
  • applicationContext.getBean(beanDefinitionName) : 빈 이름으로 빈 객체를 반환한다.
  • beanDefinition.getRole() : 빈의 정보 중 역할을 반환한다.
  • BeanDefinition.ROLE_INFRASTRUCTURE : 스프링 내부에서 등록해 사용하는 빈
  • BeanDefinition.ROLE_APPLICATION : 개발자가 직접 등록한 애플리케이션 빈

스프링 빈 조회 (기본)

스프링 컨테이너에 등록된 빈을 조회하는 방법

  • applicationContext.getBean(빈이름, 타입)
MemberService memberService = applicationContext.getBean("memberService", MemberService.class);
  • applicationContext.getBean(타입)
MemberService memberService = applicationContext.getBean(MemberService.class);

동일한 타입이 둘 이상일 때

  • applicationContext.getBeansOfType()
Map<String, MemberRepository> beansOfType = applicationContext.getBeansOfType(MemberRepository.class);

출력하면

스프링 빈 상속관계

스프링 빈은 부모 타입으로 조회하면 자식 타입도 함께 조회된다. 따라서, 자바 객체의 최상위에 있는 Object 타입으로 조회하면 모든 스프링 빈이 조회된다.

BeanDefinition

스프링이 XML과 자바 설정 클래스 이 두 가지 방법을 이용하여 컨테이너를 설정할 수 있도록 하는 데에는 BeanDefinition이라는 추상화가 중심에 있다.

BeanDefinition이 어떤 설정 형식을 읽어서 만들어지면 이 안에는 빈 설정 메타정보가 들어있다. 스프링 컨테이너는 이 메타정보를 통해 스프링 빈을 생성한다.

BeanDefinition 정보

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

**참고 : 스프링 핵심 원리 - 기본편(김영한)

profile
Record What I Learned

1개의 댓글

comment-user-thumbnail
2023년 12월 9일

의존관계 자동주입에 대해서는 나중에 추가하기

답글 달기