인프런 커뮤니티 질문&답변

Jeongwook Kim님의 프로필 이미지

작성한 질문수

스프링 핵심 원리 - 기본편

@Configuration과 싱글톤강의를 따라하는데 값이 다르게 나옵니다.

해결된 질문

작성

·

537

·

수정됨

0

@Configuration 어노테이션 안의 AppConfig 클래스에서 memberService와 orderService에 들어가는 memberRepository 설정이 각각 new로 MemoryMemberRepository를 생성한다 하더라도 그 MemberRepository들은 같은 싱글톤으로 있다는 강의 내용은 전부 이해했습니다.

그런데 강의 내용 그대로 따라 코딩을 하였는데 결과값은 각각 다른 MemberRepository를 갖게 되더라구요... 그래서 제가 잘못한 것이 있는지 알 수 있을까 해서 질문드립니다.


AppConfig

@Configuration
public class AppConfig {
    @Bean
    public static MemberRepository memberRepository() {
        return new MemoryMemberRepository();
    }

    @Bean
    public static DiscountPolicy discountPolicy() {
        // return new FixDiscountPolicy();
        return new RateDiscountPolicy();
    }

    @Bean
    public MemberService memberService() {
        return new MemberServiceImpl(memberRepository());
    }

    @Bean
    public OrderService orderService() {
        return new OrderServiceImpl(memberRepository(), discountPolicy());
    }
}

MemberServiceImpl

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);
    }

    @Override
    public Member findMember(Long memberId) {
        return memberRepository.findById(memberId);
    }

    // 스프링의 @Configuration 싱글톤 테스트를 위한 Getter
    public MemberRepository getMemberRepository() {
        return memberRepository;
    }
}

OrderServiceImpl

public class OrderServiceImpl implements OrderService {

    private final MemberRepository memberRepository;
    private final DiscountPolicy discountPolicy;

    public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
        this.memberRepository = memberRepository;
        this.discountPolicy = discountPolicy;
    }

    @Override
    public Order createOrder(Long memberId, String itemName, int itemPrice) {

        Member member = memberRepository.findById(memberId);
        int discountPrice = discountPolicy.discount(member, itemPrice);
        return new Order(memberId, itemName, itemPrice, discountPrice);
    }

    // 스프링의 @Configuration 싱글톤 테스트를 위한 Getter
    public MemberRepository getMemberRepository() {
        return memberRepository;
    }
}

ConfigurationSingletonTest

public class ConfigurationSingletonTest {
    @Test
    void configurationTest() {
        ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);

        MemberServiceImpl memberService = ac.getBean("memberService", MemberServiceImpl.class);
        OrderServiceImpl orderService = ac.getBean("orderService", OrderServiceImpl.class);
        MemberRepository memberRepository = ac.getBean("memberRepository", MemberRepository.class);

        System.out.println("memberService -> memberRepository = " + memberService.getMemberRepository());
        System.out.println("orderService -> memberRepository = " + orderService.getMemberRepository());
        System.out.println("memberRepository = " + memberRepository);

        assertThat(memberService.getMemberRepository()).isSameAs(memberRepository);
        assertThat(orderService.getMemberRepository()).isSameAs(memberRepository);
    }
}

결과


제가 강의 내용을 이해한대로라면 저렇게 3개가 같은 MemoryMemberRepository를 가져야 할것같은데 제가 뭔가 잘못 작성한것이 있을까요...?

답변 1

0

Jeongwook Kim님의 프로필 이미지
Jeongwook Kim
질문자

답변 올리자마자 해결하게되긴했네요... AppConfig에서 static을 지우니 3개의 memberRepository가 같은 값을 갖게 되네요....

그럼 혹시 왜 static을 넣으면 다른 값을 갖게 되는지 알 수 있을까요?

안녕하세요. Jeongwook Kim님, 공식 서포터즈 OMG입니다.
.

static이 포함된 정적인 메서드인 경우 싱글톤을 보장하지 않습니다.

 

다음 링크를 참고해주세요 :)
.
감사합니다.