김영한님의 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술을 보면서 공부한 내용입니다.
회원 서비스와 리포지토리에 @Service, @Repository, @Autowired 등을 사용해서 컴포넌트 스캔으로 자동 등록하고 사용했었는데, 이제는 해당 어노테이션들을 제거하고 진행하는 방법이다.
먼저, 회원 서비스와 리포지토리에 있는 어노테이션을 제거한다.
public class MemoryMemberRepository implements MemberRepository {
private static Map<Long, Member> store = new HashMap<>();
private static long sequence = 0L;
public class MemberService {
private final MemberRepository memberRepository;
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository; // 생성자를 이용해 외부에서 주입하기
}
SpringConfig
클래스를 만든다.
@Configuration
어노테이션을 걸고 @Bean
을 작성하여 스프링 빈에 등록해준다.
@Configuration
public class SpringConfig {
@Bean // Spring Bean을 등록한다는 의미
public MemberService memberService(){
// memberService를 해당 로직을 호출해서 Spring Bean에 등록해줌
return new MemberService(memberRepository());
}
@Bean
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
}
이를 통해 @Autowired
를 사용할 때와 동일하게 의존성 주입(DI)가 발생하게 된다.
→ 테스트 실행시 스프링 컨테이너의 도움 없이 MemberService가 가지고 있는 여러 Repository를 자유롭게 변경하면서 테스트 할 수 있어야 한다. 그런데 필드 주입을 사용하면, 스프링 컨테이너가 없을 때 의존하는 객체를 변경할 수 있는 방법이 없다. 그러므로 사용을 지양한다.
→ public하기 노출이 되므로 중간에 바꿔질 수 있는 문제가 있다.
→ 스프링 컨테이너의 도움 없이 직접 new MemberService(new XxxRepository)와 같은 식으로 스프링 컨테이너의 도움 없이 원하는 객체를 변경 또는 MemberService를 새로 생성하고 주입해서 테스트 하거나 실행할 수 있다.