본문 바로가기
Java , Spring/Spring

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

by 방배킹 2023. 3. 22.

스프링 컨테이너 생성

ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);

 

  • ApplicationContext 를 스프링 컨테이너라 한다.
  • ApplicationContext 는 인터페이스다.
  • 스프링 컨테이너는 XML을 기반으로 만들 수 있고, 애노테이션 기반으로 만들 수 있다.
  • new AnnotationConfigApplicationContext(AppConfig.class); 는 ApplicationContext 인터페이스의 구현체이다.

스프링 컨테이너 생성 과정

1. 스프링 컨테이너 생성

  • 스프링 컨테이너를 생성할 때는 구성 정보를 지정해줘야 한다.
  • 해당 예시에서는 AppConfig.class를 구성 정보로 지정헀다.

2. 스프링 빈 등록

  • 스프링 컨테이너가 스프링 빈 저장소에 빈을 등록한다.
  • 전달 받은 AppConfig.class 에서 @Bean이 붙은것을 모두 호출한다.
  • 일반적으로  해당 메서드의 이름으로 등록하고 반환 객체를 빈객체로 등록한다.

빈 이름은 항상 다른 이름을 부여해야 한다, 중복 절대 금지

 

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

 

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

  • 스프링 컨테이너는 설정 정보를 참고해서 의존관계를 주입한다 (DI)
  • 단순히 자바 코드를 호출하는것 처럼 보이지만, 차이가 존재한다. (추후 싱글톤 컨테이네에서 다시 다룰 예정)

참고

  • 스프링은 빈을 생성하고 의존관계를 주입하는 단계가 나누어져 있다.

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

@Test
@DisplayName("모든 빈 출력하기")
void findAllBean() {
	String[] beanDefinitionNames = ac.getBeanDefinitionNames();
	for (String beanDefinitionName : beanDefinitionNames) {
		Object bean = ac.getBean(beanDefinitionName);
		System.out.println("name=" + beanDefinitionName + " object=" + bean);
 	}
 }
  • 스프링에 등록된 모든 빈을 출력할 수 있다.
  • ac.getBeanDefinitionNames() : 스프링에 등록된 모든 빈 이름을 조회한다
  • ac.getBean() : 빈 이름으로 빈 객체(인스턴스)를 조회한다
//Role ROLE_APPLICATION: 직접 등록한 애플리케이션 빈
//Role ROLE_INFRASTRUCTURE: 스프링이 내부에서 사용하는 빈
if (beanDefinition.getRole() == BeanDefinition.ROLE_APPLICATION) {
	Object bean = ac.getBean(beanDefinitionName);
	System.out.println("name=" + beanDefinitionName + " object=" + bean);
}
  • 해당 if문을 통해 애플리케이션 빈만 출력할 수 있다.
  • ROLE_APPLICATION : 일반적으로 사용자가 정의한 빈
  • ROLE_INFRASTRUCTURE : 스프링이 내부에서 사용하는 빈

스프링 빈 조회 - 기본

이름,타입,구체타입 으로 스프링 빈을 조회 할 수 있다.

스프링 빈 조회 - 동일한 타입이 둘 이상

@Configuration
	static class SameBeanConfig {
    
	@Bean
 	public MemberRepository memberRepository1() {
 		return new MemoryMemberRepository();
 	}
    
 	@Bean
	public MemberRepository memberRepository2() {
		return new MemoryMemberRepository();
    }
}

타입으로 조회를 할때 같은 타입의 스프링 빈이 둘이상 존재하면 오류가 발생한다. -> 이때는 빈의 이름을 지정해줘야 한다.

@Test
@DisplayName("타입으로 조회시 같은 타입이 둘 이상 있으면, 빈 이름을 지정하면 된다")
void findBeanByName() {
	MemberRepository memberRepository = ac.getBean("memberRepository1",MemberRepository.class);
	assertThat(memberRepository).isInstanceOf(MemberRepository.class);
}

스프링 빈 조회 - 상속 관계

부모 타입으로 조회하면, 자식 타입도 함께 조회된다.

@Configuration
static class TestConfig {
	@Bean
	 public DiscountPolicy rateDiscountPolicy() {
	 return new RateDiscountPolicy();
	 }
	 @Bean
	 public DiscountPolicy fixDiscountPolicy() {
	 return new FixDiscountPolicy();
	 }
}

다음과 같이 빈을 등록했을때

부모타입인 DiscountPolicy 로 조회를 하면 오류가 생긴다

  • 빈 이름을 지정해준다. -> ac.getBean("rateDiscountPolicy", DiscountPolicy.class);
  • 특정 하위 타입으로 지정해준다. -> ac.getBean(DiscountPolicy.class));

BeanFactory와 ApplicationContext

BeanFactory

  • 스프링 컨테이너의 최상위 인터페이스
  • 스프링 빈을 관리하고 조회하는 역할을 담당한다.
  • getBean() 제공

 

ApplicationContext

  • BeanFactory 기능을 모두 상속 받아 제공한다.
  • 빈을 관리하고 검색하는 기능은 BeanFactory가 제공해준다, ApplicationContext의 기능은??
  • 많은 부가기능을 제공한다.

즉, ApplicationContext는 BeanFactory에서 상속받은 빈 관리 기능 + 추가적인 부가기능

일반적으로 BeanFactory는 사용하지 않고 추가 기능이 있는 ApplicationContext를 사용한다.

다양한 설정 형식 지원 - 자바 코드, XML

애노테이션 기반 자바 코드 설정 사용

  • new AnnotationConfigApplicationContext(AppConfig.class)에서 AppConfig.class의 설정 정보를 전달

 

XML 설정 사용

  • 스프링 부트를 사용하면서 잘 사용하지 않지만 아직 많은 레거시 프로젝트 들이 XML로 되어있다.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://
www.springframework.org/schema/beans/spring-beans.xsd">
 <bean id="memberService" class="hello.core.member.MemberServiceImpl">
 <constructor-arg name="memberRepository" ref="memberRepository" />
 </bean>
 <bean id="memberRepository"
class="hello.core.member.MemoryMemberRepository" />
 <bean id="orderService" class="hello.core.order.OrderServiceImpl">
 <constructor-arg name="memberRepository" ref="memberRepository" />
 <constructor-arg name="discountPolicy" ref="discountPolicy" />
 </bean>
 <bean id="discountPolicy" class="hello.core.discount.RateDiscountPolicy" />
</beans>
  • appConfig.xml을 만들어서 빈을 등록하고 해당 정보를 넘겨준다.
  • 애노테이션 기반 방식과 매우 유사하다.

스프링 빈 설정 메타 정보 - BeanDefinition

스프링은 어떻게 다양한 설정 형식을 지원하는 것일까? -> BeanDefinition이라는 추상화 덕분이다.

 

 

인프런 김영한 강사님의 Spring 핵심입문 정리 강의를 듣고 정리한 내용입니다.

'Java , Spring > Spring' 카테고리의 다른 글

컴포넌트 스캔  (0) 2023.03.29
싱글톤 컨테이너  (0) 2023.03.23
Spring Boot (3) 정적, MVC, API  (0) 2023.01.30
Spring Boot (2) Welcome page 만들기  (1) 2023.01.30
Spring Boot (1) 스프링 부트 시작하기  (0) 2023.01.30

댓글