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

2023. 9. 26. 07:13LECTURES/스프링 핵심 원리 기본편

스프링 컨테이너

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

스프링 컨테이너 생성 과정

  1. 스프링 컨테이너 생성
    • new AnnotationConfigApplicationContext(AppConfig.class)
    • 구성 정보 지정 (AppConfig.class)
  2. 스프링 빈 등록
    • 파라미터로 넘어온 설정 클래스 정보를 사용해서 스프링 빈 등록
    • 빈 이름
      • 메서드 이름을 사용
      • 직접 부여하는 방법 : @Bean(name="beanName")
      • 항상 다른 이름을 부여해야 함
        • 같은 이름을 부여하면, 다른 빈이 무시되거나 기존 빈을 덮어버리거나 설정에 따라 오류 발생
  3. 스프링 빈 의존관계 설정 - 준비
  4. 스프링 빈 의존관계 설정 - 완료
    • 스프링 컨테이너는 설정 정보를 참고해서 의존관계를 주입함

컨테이너에 등록된 빈 조회

코드

  • ac.getBeanDefinitionName() : 스프링에 등록된 모든 빈 이름 조회
  • ac.getBean() : 빈 이름으로 빈 객체를 조회
  • beanDefinition.getRole()
    • ROLE_APPLICATION : 일반적으로 사용자가 정의한 빈
    • ROLE_INFRASTRUCTURE : 스프링이 내부에서 사용하는 빈

스프링 빈 조회 - 기본

코드

  • ac.getBean(빈이름, 타입)
  • ac.getBean(타입)
  • 조회 대상인 스프링 빈이 없으면 NoSuchBeanDefinitionException 발생
  • 구체 타입으로 조회하면 변경 시 유연성이 떨어짐 -> 권장 X

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

코드

  • 타입으로 조회시 같은 타입의 빈이 둘 이상이면 NoUniqueBeanDefinitionException 발생
  • 빈 이름을 지정하여 해결
  • ac.getBeansOfType(빈타입) : 해당 타입의 모든 빈 조회

스프링 빈 조회 - 상속 관계

코드

  • 부모 타입으로 조회하면, 자식 타입도 함께 조회됨
  • Object 타입으로 조회하면, 모든 스프링 빈 조회됨

BeanFactory와 ApplicationContext

AnnotationConfigApplicationContext -> ApplicationContext(interface) -> BeanFactroy(interface)

BeanFactory

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

ApplicationContext

  • BeanFactory 기능을 모두 상속받아 제공
  • 빈을 관리하고 조회하는 기능뿐 아니라 수많은 부가기능 제공
    • MessageSource : 국제화 기능
      • 한국에서 들어오면 한국어로, 영어권에서 들어오면 영어로 출력
    • EnvironmentCapable : 환경변수
      • 로컬, 개발, 운영 등을 구분해서 처리
    • ApplicationEventPublisher : 애플리케이션 이벤트
      • 이벤트를 발행하고 구독하는 모델을 편리하게 지원
    • ResourceLoader : 편리한 리소스 조회
      • 파일, 클래스패스, 외부 등에서 리소스를 편리하게 조회

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

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

  • AnnotationConfigApplicationContext를 사용하여 자바 코드로 된 설정 정보를 넘기면 됨
  • AppConfig.java
@Configuration
public class AppConfig {

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

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

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

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

XML 설정 사용

  • 최근에는 스프링 부트를 사용하면서 거의 사용하지 않고, 레거시 프로젝트들이 XML로 되어 있음
  • GenericXmlApplicationContext를 사용하여 xml 설정 파일을 넘기면 됨
  • 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>

    <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>

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

코드

  • BeanDefinitionReader를 사용하여 설정 정보를 읽고 BeanDefinition 생성
  • @Bean 또는 <bean> 하나 당 메타 정보가 생성됨
  • 스프링 컨테이너는 이 메타정보를 기반으로 스프링 빈 생성
  • BeamDefinition 정보
    • BeanClassName : 생성할 빈의 클래스 명
    • factoryBeanName : 팩토리 역할의 빈을 사용할 경우 이름
    • factoryMethodName : 빈을 생성할 팩토리 메서드 지정
    • Scope : 싱글톤
    • lazyInit : 스프링 컨테이너를 생성할 때 빈을 생성하는 것이 아니라, 실제 빈을 사용할 때까지 최대한 생성을 지연처리하는지 여부
    • initMethodName : 빈을 생성하고, 의존관계를 적용한 뒤에 호출되는 초기화 메서드 명
    • DestroyMethodName : 빈의 생명주기가 끝나서 제거하기 직전에 호출되는 메서드 명
    • Constructor arguments, Properties : 의존관계 주입에서 사용
 

스프링 핵심 원리 - 기본편 - 인프런 | 강의

스프링 입문자가 예제를 만들어가면서 스프링의 핵심 원리를 이해하고, 스프링 기본기를 확실히 다질 수 있습니다., 스프링 핵심 원리를 이해하고, 성장하는 백엔드 개발자가 되어보세요! 📢

www.inflearn.com

 

'LECTURES > 스프링 핵심 원리 기본편' 카테고리의 다른 글

컴포넌트 스캔  (0) 2023.09.26
싱글톤 컨테이너  (0) 2023.09.26
객체 지향 원리 적용  (0) 2023.09.26
예제 만들기  (0) 2023.09.26
객체 지향 설계와 스프링  (0) 2023.09.26