이전 포스트에서는 간단한 자바 프로젝트를 만들어 객체 지향 원리를 적용해보았다. 이번 포스트에서는 프로젝트에 스프링을 간단히 적용해볼 것이며, 스프링 컨테이너와 스프링 빈에 대해서 알아보도록 하자.
스프링 컨테이너와 스프링 빈
스프링으로 전환하기
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(스프링 컨테이너)는 인터페이스이며, AnnotationConfigApplicationContext는 ApplicationContext의 구현체이다.
스프링 컨테이너 생성 과정
- new AnnotationConfigApplicationContext(AppConfig.class)를 통해 스프링 컨테이너를 생성할 때 AppConfig 구성 정보를 활용한다.
- 스프링 컨테이너는 파라미터로 넘어온 설정 클래스 정보(AppConfig)를 사용해서 스프링 빈을 등록한다. (memberService, memberRepository)
- 스프링 컨테이너는 설정 정보를 참고해서 의존관계를 주입(DI)한다.
컨테이너 내의 빈 조회하기
빈을 조회하는 가장 기본적인 방법은 getBean() 메서드를 사용하는 것이다.
- applicationContext.getBean(빈이름, 타입)
- applicationContext.getBean(타입)
파라미터로 입력한 이름/타입의 빈이 컨테이너에 없으면 예외가 발생한다. 타입만 지정해서 조회할 때 해당 타입의 빈이 두 개 이상인 경우에도 예외가 발생하는데, 이때는 이름도 같이 지정해주면 된다.
여러 개의 빈이 상속관계를 가질 때, 부모 타입으로 조회하면 자식 타입도 함께 조회된다. 이때도 조회되는 빈이 두 개 이상이면 예외가 발생하므로 이름을 같이 지정해주어야 한다.
이 포스트는 인프런의 [스프링 핵심 원리 - 기본편] (김영한) 강의를 수강하고 정리한 글입니다.
'Java > [스프링 핵심 원리]' 카테고리의 다른 글
[스프링 핵심 원리] 컴포넌트 스캔(@ComponentScan) (0) | 2021.12.12 |
---|---|
[스프링 핵심 원리] 싱글톤 컨테이너와 @Configuration (0) | 2021.12.11 |
[스프링 핵심 원리] 스프링 설정 파일 알아보기 - BeanFactory와 ApplicationContext, BeanDefinition (0) | 2021.12.08 |
[스프링 핵심 원리] JAVA 프로젝트에 OOP 원리 적용하기 (SRP, OCP, DIP) (0) | 2021.12.05 |
[스프링 핵심 원리] 객체 지향 SOLID 원칙과 Spring의 관계 (0) | 2021.12.03 |
댓글