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

Spring Container, Spring Bean

이전 글에서 AppConfig로 MemberService에 의존성을 넣어줄 수 있었다. 스프링 컨테이너에 적용하면서 스프링 컨테이너에 대해 알아보자


스프링 컨테이너

@Configuration
public class AppConfig{

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

// memberService에 join, find 구현되있다고 가정

public class MemberApp {

  public static void main(String[] args){
//  AppConfig appConfig = new AppConfig(); 기존의 방법
//  MemberService memberService = appConfig.memberService();
    ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
    MemberService memberService = applicationContext.getBean("memberService", MemberService.class);

    Member member = new Member(1L, "memberA", Grade.VIP);
    memberService.join(member);

    Member findMember = memberService.findMember(1L);
    System.out.println("new member = " + member.getName());
    System.out.println("find Member = " + findMember.getName());
  }
}
  • ApplicationContext를 스프링 컨테이너라 한다.
  • 기존에는 개발자가 AppConfig를 사용해서 직접 객체를 생성하고 DI를 했지만(주석 처리한 방법), 이제부터는 스프링 컨테이너를 통해서 사용한다.
  • 스프링 컨테이너는 @Configuration 붙은 AppConfig를 설정(구성) 정보로 사용한다. 여기서 @Bean 이라 적힌 메서드를 모두 호출해서 반환된 객체를 스프링 컨테이너에 등록한다. 이렇게 스프링 컨테이너에 등록된 객체를 스프링 빈이라 한다.
  • 이전에는 개발자가 필요한 객체를 AppConfig를 사용해서 직접 조회했지만, 이제부터는 스프링 컨테이너를 통해서 필요한 스프링 빈(객체)를 찾아야 한다. 스프링 빈은 applicationContext.getBean() 메서드를 사용해서 찾을 수 있다.
  • 코드가 약간 더 복잡해진 것 같은데, 스프링 컨테이너를 사용하면 어떤 장점이 있는지 알아보자.

스프링 컨테이너 생성

스프링 컨테이너가 생성되는 과정을 알아보자.

//스프링 컨테이너 생성
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
  • ApplicationContext는 인터페이스이다.
  • newAnnotationConfigApplicationContext(AppConfig.class);는 ApplicationContext 인터페이스의 구현체이다.
  • 스프링 컨테이너는 XML을 기반으로 만들 수도 있고, 애노테이션 기반의 자바 설정 클래스로도 만들 수 있다.
  • 직전의 AppConfig를 사용했던 방식이 애노테이션 기반의 자바 설정 클래스로 스프링 컨테이너를 만든 것

XML 설정 사용

최근에는 스프링 부트를 많이 사용하면서 XML기반의 설정은 잘 사용하지 않는다. 궁금하면 찾아보자


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

1. 스프링 컨테이너 생성

img

  • new AnnotationConfigApplicationContext(AppConfig.class)
  • 스프링 컨테이너를 생성할 때는 구성 정보를 지정해주어야 한다.
  • 여기서는 AppConfig.class를 구성 정보로 지정
2. 스프링 빈 등록

img

  • 빈 이름은 메서드 이름을 사용한다.
  • 빈 이름을 직접 부여할 수 도 있다.
    • @Bean(name = “memberService2”)

*주의: 빈 이름은 항상 다른 이름을 부여해야 함. 같은 이름을 부여하면, 다른 빈이 무시되거나, 기존 빈을 덮어 버리거나 설정에 따라 오류가 발생.

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

img

  • 스프링 컨테이너는 설정 정보를 참고해서 의존관계를 주입(DI)한다.

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

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

    img

  • 어떻게 이런 다양한 설정 형식을 지원할까? 그 중심에는 BeanDefinition이라는 추상화가 있다.

    img

  • 조금 더 깊이 있게 들어가보자면

    img

  • AnnotationConfigApplicationContext 는 AnnotatedBeanDefinitionReader 를 사용해서 AppConfig.class 를 읽고 BeanDefinition 을 생성한다.
  • GenericXmlApplicationContext 는 XmlBeanDefinitionReader 를 사용해서 appConfig.xml 설정정보를 읽고 BeanDefinition 을 생성한다.
  • 새로운 형식의 설정 정보가 추가되면, XxxBeanDefinitionReader를 만들어서 BeanDefinition 을 생성하면 된다.
  • 실무에서 BeanDefinition을 직접 정의하거나 사용할 일은 거의 없으므로 깊게 이해하는 것 보단 이렇게 사용하는 구나 하고 넘어가자.

참고: Spring Core

*틀린 부분이 있으면 언제든지 말씀해 주시면 공부해서 수정하겠습니다.


© 2022. All rights reserved.

Powered by 애송이