Blog

[SpringCore] 스프링 컨테이너와 스프링 빈 - 기존 DI 자바 코드를 Spring 컨테이너 활용 코드로 리팩토링

Category
Author
Tags
PinOnMain
1 more property
이전 AppConfig까지 과정은 순수 Java로 진행되었던 부분을 Spring을 활용하여 리팩토링 하기
Table of Content

스프링 컨테이너의 사용

DI 컨테이너 역할을 해주던 AppConfig를 Spring 어노테이션을 사용하여 리팩토링한다.

기존 코드 AppConfig.java

public class AppConfig { public MemberService memberService() { return new MemberServiceImpl(memberRepository()); } public MemberRepository memberRepository() { return new MemoryMemberRepository(); } public OrderService orderService() { return new OrderServiceImpl(memberRepository(), discountPolicy()); } public DiscountPolicy discountPolicy() { return new RateDiscountPolicy(); } }
Java
복사

Spring Container에 빈을 등록하는 AppConfig.java

@Configuration public class AppConfig { @Bean public MemberService memberService() { return new MemberServiceImpl(memberRepository()); } @Bean public MemberRepository memberRepository() { return new MemoryMemberRepository(); } @Bean public OrderService orderService() { return new OrderServiceImpl(memberRepository(), discountPolicy()); } @Bean public DiscountPolicy discountPolicy() { return new RateDiscountPolicy(); } }
Java
복사
@Configuration 어노테이션으로 해당 클래스를 스프링 구성 정보로 지정한다.
@Bean 어노테이션으로 해당 메서드를 스프링 빈으로 등록(메서드명=빈이름) 할 것을 지정한다.
1.
빈을 생성하는 단계
2.
빈의 관계를 설정하는 단계
위 그림처럼 빈으로 등록된 객체들은 서로 의존관계가 설정되고 사용 준비 상태가 된다.

스프링 컨테이너로부터 빈을 찾아 사용하도록 수정

기존 DI를 AppConfig 객체에서 통해서 불러왔지만 위처럼 AppConfig를 스프링 설정 정보로 사용하면서 스프링 컨테이너인 ApplicationContext을 생성하면서 빈(Bean)을 등록하게 된다.
등록된 빈은 메소드 이름으로 등록되며 getBean을 통해서 스프링 컨테이너에 등록된 빈을 사용 할 수 있다.
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.BASIC); memberService.join(member); Member findMember = memberService.findMember(1L); System.out.println("new Member = " + member.getName()); System.out.println("new Member = " + findMember.getName()); } }
Java
복사

등록된 빈 확인

그림처럼 스프링 컨테이너에 빈이 등록되었다고 하지만 실제로 빈이 등록되어있는지 확인해보는 테스트 코드를 작성해본다.
스프링 컨테이너 ApplicationContext의 실제 구현체인 AnnotationConfigApplicationContext 를 생성하고 이를 통해서 실제로 AppConfig 정보를 통해 빈이 등록되는 것을 확인해보고자 한다.
빈이 등록된 이름은 AnnotationConfigApplicationContext의 스프링 컨테이너에서 getBeanDefinitionNames 메소드를 통해 등록된 빈의 배열을 조회 할 수 있다.
package hello.core.beanfind; import hello.core.AppConfig; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class ApplicationContextInfoTest { AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class); @Test @DisplayName("등록된 모든 빈 출력해보기") void findAllBean() { String[] beanDefinitionNames = ac.getBeanDefinitionNames(); for (String beanDefinitionName : beanDefinitionNames) { Object bean = ac.getBean(beanDefinitionName); System.out.println("name = " + beanDefinitionName + "object = " + bean); } } @Test @DisplayName("애플리케이션 빈 출력해보기") void findApplicationBean() { String[] beanDefinitionNames = ac.getBeanDefinitionNames(); for (String beanDefinitionName : beanDefinitionNames) { BeanDefinition beanDefinition = ac.getBeanDefinition(beanDefinitionName); //if (beanDefinition.getRole() == BeanDefinition.ROLE_INFRASTRUCTURE) { // 스프링이 내부에서 사용하는 빈 if (beanDefinition.getRole() == BeanDefinition.ROLE_APPLICATION) { // 스프링에 사용자가 정의(등록)한 빈 Object bean = ac.getBean(beanDefinitionName); System.out.println("name = " + beanDefinitionName + "object = " + bean); } } } }
Java
복사
Search
 | Main Page | Category |  Tags | About Me | Contact | Portfolio