Blog

[SpringCore] 컴포넌트 스캔 - 스프링 빈 수동 → 자동 주입 변경

Category
Author
Tags
PinOnMain
1 more property
지금까지 연습으로는 자바 코드의 @Bean이나 XML의 <bean> 태그를 통해서 스프링 설정 정보에 직접 나열했었다. 자동 주입을 활용해보자.
Table of Content

자동 주입을 위한 컴포넌트 스캔

스프링은 설정 정보가 없어도 자동으로 컴포넌트를 찾아 스프링 빈으로 등록해주는 기능을 제공한다.
이전에 작성해온 AppConfig.java에서는 @Bean 어노테이션으로 수동으로 직접 설정 정보를 작성하고, 의존 관계도 명시했었다.
package hello.core; import hello.core.discount.DiscountPolicy; import hello.core.discount.RateDiscountPolicy; import hello.core.member.MemberRepository; import hello.core.member.MemberService; import hello.core.member.MemberServiceImpl; import hello.core.member.MemoryMemberRepository; import hello.core.order.OrderService; import hello.core.order.OrderServiceImpl; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @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
복사
이제 스프링에서는 @ComponentScan@Component 등록된 클래스 찾아 빈으로 등록한다 → 의존관계는 @Autowired 를 통해 주입된다.
AutoAppConfig.java로 자동 주입과 관련된 설정 정보를 새로 작성했다. 실제로는 AppConfig에 작업해도 되지만 비교를 위해 새로 작성하였다.
package hello.core; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.FilterType; @Configuration @ComponentScan public class AutoAppConfig { }
Java
복사
스프링 빈으로 등록할 대상이 되는 클래스들에 @Component 를 작성해준다. 생성자 주입으로 의존 관계를 등록했던 부분은 @Autowired 를 작성한다.
MemberServiceImpl, OrderServiceImpl, FixDiscountPolicy, MemoryMemberRepository 등 스프링 빈으로 등록할 클래스의 코드를 변경했다.
@Component public class MemberServiceImpl implements MemberService{ private final MemberRepository memberRepository; @Autowired public MemberServiceImpl(MemberRepository memberRepository) { this.memberRepository = memberRepository; } @Override public void join(Member member) { memberRepository.save(member); } ... }
Java
복사
@Component public class FixDiscountPolicy implements DiscountPolicy { private int discountFixAmout = 1000; // 1000원 기본 할인 ... }
Java
복사
@Component public class OrderServiceImpl implements OrderService{ private final MemberRepository memberRepository; private final DiscountPolicy discountPolicy; @Autowired public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) { this.memberRepository = memberRepository; this.discountPolicy = discountPolicy; } ... }
Java
복사
@Component public class MemoryMemberRepository implements MemberRepository{ private static Map<Long, Member> store = new HashMap<>(); ... }
Java
복사

자동 주입 테스트

위 처럼 @ComponentScan 이 정상적으로 작동하는지 테스트 코드로 확인한다.
package hello.core.componentscan; import hello.core.AutoAppConfig; import hello.core.member.MemberService; import org.junit.jupiter.api.Test; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import static org.assertj.core.api.Assertions.assertThat; public class AutoAppConfigTest { @Test void basicScan() { AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AutoAppConfig.class); MemberService memberService = ac.getBean(MemberService.class); assertThat(memberService).isInstanceOf(MemberService.class); } }
Java
복사
자동 주입을 확인하기 위해 작성한 AutoAppConfig 클래스를 설정 정보로 불러와서 실행해보면
@Component라고 작성한 클래스들이 singleton 인스턴스들로 생성되었다는 로그와
@Autowired 로 작성한 생성자들을 통해서 각 구현체들과 연관관계가 설정되는 것을 확인 할 수 있다.

1. @ComponentScan 이 하는 일

@Component가 붙은 모든 클래스를 스프링 빈으로 등록한다.
스프링 빈의 기본 이름은 클래스명으로 등록되며, 맨 앞글자만 소문자로 사용
빈의 이름을 직접 커스텀하기 위해서는 @Component(”memberService2”) 처럼 직접 기입하면 된다.

2. @Autowired 가 하는 일

생성자에 @Autowired가 지정된 경우 스프링 컨테이너가 자동으로 해당 스프링 빈을 찾아서 생성자 주입을 한다.
이때 기본 조회 전략은 타입이 같은 빈을 찾아서 주입한다.
getBean(MemberRepository.class)와 같다고 보면 된다.
Search
 | Main Page | Category |  Tags | About Me | Contact | Portfolio