본문 바로가기
Java/[스프링 핵심 원리]

[스프링 핵심 원리] 스프링 컨테이너와 스프링 빈

2021. 12. 7.
반응형

이전 포스트에서는 간단한 자바 프로젝트를 만들어 객체 지향 원리를 적용해보았다. 이번 포스트에서는 프로젝트에 스프링을 간단히 적용해볼 것이며, 스프링 컨테이너와 스프링 빈에 대해서 알아보도록 하자.

 

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

스프링으로 전환하기

package hello.core;
import hello.core.member.MemberRepository;
import hello.core.member.MemberService;
import hello.core.member.MemberServiceImpl;
import hello.core.member.MemoryMemberRepository;

public class AppConfig {

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

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

지난 시간에 작성한 AppConfig 파일이다. 순수 자바 코드로 이루어져 있다. 그러면 이 코드를 스프링으로 전환해보자.

 

package hello.core;
import hello.core.member.MemberRepository;
import hello.core.member.MemberService;
import hello.core.member.MemberServiceImpl;
import hello.core.member.MemoryMemberRepository;

@Configuration
public class AppConfig {

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

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

달라진 부분이 보이는가? 기존 코드에서 @Configuration, @Bean 애노테이션만 추가되었다. @Configuration 애노테이션은 설정을 구성한다는 의미AppConfig에 붙여주었다. 또한 메서드에 @Bean을 붙여주면 스프링 컨테이너에 스프링 빈으로 등록한다. 위 설정에서 등록한 스프링 빈을 사용하려면 아래 예시 코드처럼 작성하면 된다.

 

package hello.core;

import hello.core.member.Grade;
import hello.core.member.Member;
import hello.core.member.MemberService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MemberApp {
    public static void main(String[] args) {

        ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
        MemberService memberService = ac.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("findMember = " + findMember.getName());
    }
}

 

스프링 컨테이너

위 코드에서 ApplicationContext스프링 컨테이너라고 한다. 이전까지는 내가 AppConfig를 이용해 직접 객체를 생성하고 DI를 했지만, 이제부터는 스프링 컨테이너를 통해서 사용한다.

 

스프링 컨테이너는 @Configuration이 붙은 AppConfig를 구성 정보로 사용한다. 여기서 @Bean이라 적힌 메서드를 모두 호출해서 반환된 객체를 스프링 컨테이너에 등록한다. 이렇게 스프링 컨테이너에 등록된 객체를 스프링 빈이라고 한다.

 

스프링 빈은 @Bean이 붙은 메서드의 이름을 빈의 이름으로 사용한다. 이제부터는 스프링 컨테이너를 통해서 필요한 스프링 빈(객체)을 찾아야 하는데, 스프링 빈은 applicationContext.getBean()을 통해 찾을 수 있다.

 

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

ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);

여기서 ApplicationContext(스프링 컨테이너)는 인터페이스이며, AnnotationConfigApplicationContextApplicationContext의 구현체이다. 

 

스프링 컨테이너 생성 과정

  1. new AnnotationConfigApplicationContext(AppConfig.class)를 통해 스프링 컨테이너를 생성할 때 AppConfig 구성 정보를 활용한다.
  2. 스프링 컨테이너는 파라미터로 넘어온 설정 클래스 정보(AppConfig)를 사용해서 스프링 빈을 등록한다. (memberService, memberRepository)
  3. 스프링 컨테이너는 설정 정보를 참고해서 의존관계를 주입(DI)한다.

 

컨테이너 내의 빈 조회하기

빈을 조회하는 가장 기본적인 방법은 getBean() 메서드를 사용하는 것이다.

  • applicationContext.getBean(빈이름, 타입)
  • applicationContext.getBean(타입)

파라미터로 입력한 이름/타입의 빈이 컨테이너에 없으면 예외가 발생한다. 타입만 지정해서 조회할 때 해당 타입의 빈이 두 개 이상인 경우에도 예외가 발생하는데, 이때는 이름도 같이 지정해주면 된다.

 

여러 개의 빈이 상속관계를 가질 때, 부모 타입으로 조회하면 자식 타입도 함께 조회된다. 이때도 조회되는 빈이 두 개 이상이면 예외가 발생하므로 이름을 같이 지정해주어야 한다. 

 

 

 

 

이 포스트는 인프런의 [스프링 핵심 원리 - 기본편] (김영한) 강의를 수강하고 정리한 글입니다.

728x90
반응형

댓글