@Configuration과 싱글톤
@Configuration이란 애너테이션은 사실 싱글톤을 위해 존재하는 녀석이다.
전에 만들었던 AppConfig를 다시 한번 잘 살펴보자.
package hello.core;
import hello.core.Discount.DiscountPolicy;
import hello.core.Discount.FixDiscountPolicy;
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();
}
}
싱글톤이라고 했는데, 이렇게되면 적어도 두 개 이상의 객체가 실행되는 것 아닐까? 이미 작성된 자바코드를 스프링이 어떻게 하는 것도 아니고…
위의 문제를 테스트를 통해 알아보기 위해, memberServiceImpl내에 객체를 반환하는 테스트용 메서드를 하나 만들어보자. 내부에 주입받은 객체 참조값 확인 용이다.
package hello.core.member;
public class MemberServiceImpl implements MemberService {
private final MemberRepository memberRepository;
public MemberServiceImpl(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
@Override
public void join(Member member) {
memberRepository.save(member); //DIP 적용
}
@Override
public Member findMember(Long memberId) {
return memberRepository.findById(memberId); //DIP 적용
}
//싱글톤 테스트 용
public MemberRepository getMemberRepositort() {
return memberRepository;
}
}
마찬가지로 orderServiceImple에도 같은 코드를 작성해주자.
게터로 가져온 두 객체가 같은 객체인지(싱글턴인지)테스트 해보자.
@Test
void configurationTest () {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
MemberServiceImpl memberService = ac.getBean("memberService", MemberServiceImpl.class);
OrderServiceImpl orderService = ac.getBean("orderService", OrderServiceImpl.class);
MemberRepository memberRepository1 = memberService.getMemberRepository();
MemberRepository memberRepository2 = memberService.getMemberRepository();
assertThat(memberRepository1).isSameAs(memberRepository2);
}