이전 포스팅에서 우리는 관심 영역을 분리함으로써 기존 코드를 개선했다. 그 과정에서 만들었던 AppConfig를 어떻게 하면 스프링으로 전환할 수 있는지 오늘 글에서 다룰 것이다.
https://braindisk.tistory.com/26
우리가 만들었던 AppConfig 클래스를 스프링의 설정 파일로 만들 것이다. 스프링의 설정 파일로 만들기 위해서는 클래스 위에 @Configuration 어노테이션을 붙여주고 @Bean 어노테이션으로 해당 메서드가 스프링 컨테이너에 등록될 빈을 반환하는 메서드라고 명시해주면 된다.
@Configuration 어노테이션의 역할은 다음과 같다.
Indicates that a class declares one or more @Bean methods and may be processed by the Spring container to generate bean definitions and service requests for those beans at runtime.
즉 하나 이상의 Bean(객체)를 정의하는 클래스라고 스프링에게 알려주는 역할이다. 이 Bean(객체)들은 스프링 컨테이너에 올라가게 되고 개발자는 이 컨테이너를 통해서 빈을 사용하게 된다.
그럼 컨테이너에 빈을 등록함으로써 얻는 장점은 뭘까? 아직 자세히 배우지는 않았지만 먼저 싱글톤의 장점이 떠오른다. 컨테이너에 빈이 등록되었다면 객체는 유일할 것이고 이 객체들을 재사용함으로써 새로운 객체를 생성할 필요가 없으므로 오버헤드가 줄어들 것이라고 예상된다. (물론 내 주관적인 생각이다)
아무튼 코드를 보면서 AppConfig가 어떻게 스프링 설정 파일로 변하는지 살펴보자. 간단하게 @Configuration, @Bean 어노테이션만으로 설정할 수 있다.
@Configuration
public class AppConfig {
@Bean
public MemberService memberService() {
return new MemberServiceImpl(memberRepository());
}
@Bean
public OrderService orderService() {
return new OrderServiceImpl(memberRepository(), discountPolicy());
}
@Bean
public MemoryMemberRepository memberRepository() {
return new MemoryMemberRepository();
}
@Bean
public DiscountPolicy discountPolicy() {
return new RateDiscountPolicy();
}
}
이제 스프링이 @Configuration이 붙은 AppConfig 설정(구성) 파일을 읽고 @Bean 어노테이션이 붙은 메서드를 모두 한 번씩 실행해서 스프링 컨테이너에 빈을 등록한다. 이렇게 스프링 컨테이너에 등록된 객체를 스프링 빈이라고 한다.
스프링 컨테이너에 등록된 스프링 빈을 사용하고 싶다면, 이제부터는 무조건 스프링 컨테이너를 거쳐야 한다(제어의 역전 IoC). 스프링 컨테이너는 ApplicationContext를 통해서 접근할 수 있고 스프링 빈은 getBean() 메서드를 통해서 얻을 수 있다.
public class MemberApp {
public static void main(String[] args) {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
MemberService memberService = applicationContext.getBean("memberService", MemberService.class);
...
}
}
스프링 컨테이너에 대해서 조금 더 자세히...
ApplicationContext는 인터페이스이며 스프링 컨텍스트라고 부른다. 스프링 컨테이너는 XML을 기반으로 만들 수 있고, 어노테이션 기반의 자바 설정(구성) 클래스로 만들 수 있다. 또한 ApplicationContext는 다양한 구현체가 있다.
스프링 컨테이너를 부를 때 'BeanFactory', 'ApplicationContext'로 구분해서 이야기하는데, 'BeanFactory'를 직접 이용하는 경우는 거의 없어서 일반적으로 ApplicationContext를 스프링 컨테이너라고 부른다.
스프링 컨테이너는 파라미터로 넘어온 설정 클래스 정보를 사용해서 아래 코드와 같이 스프링 빈을 등록한다.
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
빈을 등록할 때 빈의 이름을 지정할 수 있는데
- @Bean(name = "memberService2")
웬만하면 기본적으로 메서드 이름을 사용하는 게 좋을 듯하다. 또한 빈의 이름은 중복되어서는 안 되는데 만약 중복된다면 오류가 발생한다고 한다.
스프링 컨테이너를 구성할 때 설정 정보를 참고해서 의존관계를 주입한다. 즉 빈을 등록하면 의존관계는 알아서 설정된다. 아래 코드에서 단순히 자바 코드를 호출하는 것 같지만, 차이가 있다고 한다. (이 차이는 싱클톤 컨테이너에서 설명한다고 한다)
@Bean
public MemberService memberService() {
return new MemberServiceImpl(memberRepository());
}
위에 스프링 빈은 다음과 같은 의존 관계가 설정된다.
reference
https://www.inflearn.com/course/스프링-핵심-원리-기본편
'Spring' 카테고리의 다른 글
스프링 컴포넌트 스캔 (0) | 2022.04.03 |
---|---|
싱글톤의 단점과 스프링의 싱글톤 컨테이너 (0) | 2022.04.03 |
IoC (0) | 2022.03.25 |
객체 지향 설계 원칙을 잘 지키는 법 (0) | 2022.03.24 |
좋은 객체 지향 설계란 (0) | 2022.03.24 |