[Spring] 스프링 컨테이너와 스프링 빈

Dodam·2023년 9월 2일
0

[Spring]

목록 보기
8/9
post-thumbnail

스프링 컨테이너

  • ApplicationContext를 스프링 컨테이너라고 한다.
  • ApplicationContext는 인터페이스이다.
  • 기존에는 AppConfig를 사용해서 직접 객체를 생성하고 DI를 했지만, 이제부터는 스프링 컨테이너를 사용한다.
  • 스프링 컨테이너는 @Configuration이 붙은 AppConfig를 설정(구성) 정보로 사용한다. 여기서 @Bean이라고 적힌 메서드를 모두 호출해서 반환된 객체를 스프링 컨테이너에 등록한다. 이렇게 스프링 컨테이너에 등록된 객체를 스프링 빈(Bean)이라고 한다.
  • 스프링 빈은 @Bean이 붙은 메서드명을 스프링 빈의 이름으로 사용한다.
    (memberService, orderService)
  • 이전에는 필요한 객체를 AppConfig를 사용해서 직접 조회했지만, 이제부터는 스프링 컨테이너를 통해서 필요한 스프링 빈(객체)를 찾아야 한다.
    스프링 빈은 applicationContext.getBean() 메서드를 사용해서 찾을 수 있다.
  • 스프링 컨테이너에 객체를 스프링 빈으로 등록하고, 스프링 컨테이너에서 스프링 빈을 찾아서 사용한다.

1. 스프링 컨테이너 생성

// 스프링 컨테이너 생성
ApplicationContext applicationContext = 
					new AnnotationConfigApplicationContext(AppConfig.class);

2. 스프링 빈 등록

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

 @Bean
    public MemberService memberService() {
        return new MemberServiceImpl(memberRepository());
    }

    @Bean
    public MemberRepository memberRepository() {
        return new MemoryMemberRepository();
    }

    @Bean
    public OrderService orderService() {
        return new OrderServiceImpl(memberRepository(), discountPolicy());
    }

    @Bean
    public DiscountPolicy discountPolicy() {
        return new RateDiscountPolicy();
    }

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

모든 빈 출력하기

  • 실행하면 스프링에 등록된 모든 빈 정보를 출력할 수 있다.
  • ac.getBeanDefinitionNames(): 스프링에 등록된 모든 빈 이름을 조회
  • ac.getBean(): 빈 이름으로 빈 객체(인스턴스)를 조회

애플리케이션 빈 출력하기

  • 스프링이 내부에서 사용하는 빈은 getRole()로 구분할 수 있다.
  • ROLE_APPLICATION: 일반적으로 사용자가 정의한 빈
  • ROLE_INFRASTRUCTURE: 스프링이 내부에서 사용하는 빈

스프링 빈 조회 - 기본

스프링 컨테이너에서 스프링 빈을 찾는 가장 기본적인 조회 방법

  • ac.getBean(빈이름, 타입)
  • ac.getBean(타입)
  • 조회 대상 스프링 빈이 없으면 예외 발생
    - NoSuchBeanDefinitionException: No bean named 'xxxxx' available

    참고: 구체 타입으로 조회하면 변경 시 유연성이 떨어진다.

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

  • 타입으로 조회 시 같은 타입의 스프링 빈이 둘 이상이면 빈 이름을 지정해야 한다.
  • ac.getBeansOfType()을 사용하면 해당 타입의 모든 빈을 조회할 수 있다.

스프링 빈 조회 - 상속 관계

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

BeanFactory와 ApplicationContext

BeanFactory

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

ApplicationContext

  • BeanFactory 기능을 모두 상속받아서 제공한다.
  • 빈을 관리 및 검색하는 기능을 BeanFactory가 제공해주는데,
    그러면 BeanFactory와의 차이점은?
  • 애플리케이션을 개발할 때는 빈을 관리 및 조회하는 기능은 물론이고, 수많은 부가기능이 필요하다.

ApplicationContext가 제공하는 부가기능

  • 메시지소스를 활용한 국제화 기능(MessageSource)
    • 한국에서 들어오면 한국어로, 영어권에서 들어오면 영어로 출력
  • 환경변수(EnvironmentEapable)
    • 개발 환경을 로컬, 개발, 운영 등으로 구분해서 처리
  • 애플리케이션 이벤트(ApplicationEventPublisher)
    • 이벤트를 발행하고 구독하는 모델을 편리하게 지원
  • 편리한 리소스 조회(ResourceLoader)
    • 파일, 클래스패스, 외부 등에서 리소스를 편리하게 조회

정리

  • ApplicationContext는 BeanFactory의 기능을 상속받는다.
  • ApplicationContext는 빈 관리 기능 + 편리한 부가 기능을 제공한다.
  • BeanFactory나 ApplicationContext를 스프링 컨테이너라고 하며, 부가기능이 포함된 ApplicationContext를 주로 사용한다.

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

  • 스프링 컨테이너는 다양한 형식의 설정 정보를 받아들일 수 있도록 유연하게 설계되어 있다.
    • 자바 코드, XML, Groovy 등

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

  • new AnnotationConfigApplicationContext(AppConfig.class)
  • AnnotationConfigApplicationContext 클래스를 사용하면서 자바 코드로 된 설정 정보를 넘기면 된다.

XML 설정 사용

  • 최근에는 스프링 부트를 많이 사용하면서 XML기반의 설정은 잘 사용하지 않는다. 하지만 많은 레거시 프로젝트들이 XML로 되어 있고, 또 XML을 사용하면 컴파일 없이 빈 설정 정보를 변경할 수 있는 장점도 존재한다.
  • GenericXmlApplicationContext를 사용하면서 xml 설정 파일을 넘기면 된다.

XmlAppConfig 사용 자바 코드

public class XmlAppContext {
	
    @Test
    void xmlAppContext() {
    	ApplicationContext ac = new GenericXmlApplicationContext("appConfig.xml");
    }
}

xml 기반의 스프링 빈 설정 정보
src/main/resources/appConfig.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>
</beans>

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

  • 스프링은 다양한 형태의 설정 정보를 BeanDefinition으로 추상화해서 사용한다.

  • 역할과 구현을 개념적으로 나눈 것이다.

    • XML을 읽어서 BeanDefinition을 만들면 된다.
    • 자바 코드를 읽어서 BeanDefinition을 만들면 된다.
  • BeanDefinition을 빈 설정 메타정보라고 한다.

    • @Bean, <bean>당 각각 하나씩 메타 정보가 생성된다.
  • 스프링 컨테이너는 이 메타 정보를 기반으로 스프링 빈을 생성한다.

  • AnnotationConfigApplicationContextAnnotatedBeanDefinitionReader를 사용해서 AppConfig.class를 읽고 BeanDefinition을 생성한다.

  • GenericXmlApplicationContextXmlBeanDefinitionReader를 사용해서 appConfig.xml 설정 정보를 읽고 BeanDefinition을 생성한다.

  • 새로운 형식의 설정 정보가 추가되면, ~~BeanDefinitionReader를 만들어서 BeanDefinition을 생성하면 된다.

profile
Good things take time

0개의 댓글