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

깨위님의 프로필 이미지

작성한 질문수

스프링 핵심 원리 - 기본편

@Configuration과 싱글톤

저는 memoryRepository가 세개가 다 다릅니다.. ㅠㅠ

22.03.30 17:59 작성

·

410

0

안녕하세요.! 

원래 강의대로라면 

memberRepository 인스턴스는 모두 같은 인스턴스가 공유되어 사용되기때문에

 아래 테스트 코드가 오류가 나지 않아야하는데, 아래와 같이 인스턴스가 스프링빈에 의해서 공유되지 않고, 하나하나 각각 따로 인스턴스가 설정된 것으로 보입니다.

왜이러는걸까요,,??

 

-> 오류내용 

 

ConfigurationSingleTonTest.java코드

package hello.core.singleton;
import hello.core.AppConfig;
import hello.core.member.MemberRepository;
import hello.core.member.MemberServiceImpl;
import hello.core.order.OrderServiceImpl;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import static org.assertj.core.api.Assertions.*;
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);

}
}

 

 

 

OrderServiceImple내용

package hello.core.order;

import hello.core.discount.DiscountPolicy;
import hello.core.discount.FixDiscountPolicy;
import hello.core.member.Member;
import hello.core.member.MemberRepository;
import hello.core.member.MemoryMemberRepository;

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
//주문을 만드는 class
public Order createOrder(Long memberId, String itemName, int itemPrice) {
//맴버를 찾고
Member member = memberRepository.findById(memberId);
//맴버를 넘기고 (discount얼마나 해야하는지)
//단일 체계 원칙을 잘 지킨것이다.
//할인쪽은 order에서 관여하지 않고 , discount class를 이용하여 할인값을 반환만 받음
//할인쪽에 문제가 생기면 할인쪽만 고치며 돼서 유지보수 쉽다. (주문까지 고칠 필요는 없다)
int discountPrice = discountPolicy.discount(member,itemPrice);


// public Order(Long memberId, String itemName, int itemPrice, int discountPrice)
return new Order(memberId, itemName, itemPrice, discountPrice);
}

//테스트용도
public MemberRepository getMemberRepository() {
return memberRepository;
}
}



MemberServiceImpl내용
package hello.core.member;

//memberService의 구현체이다.
public class MemberServiceImpl implements MemberService{

//추상화에만 의존한다
private final MemberRepository memberRepository ;

//생성자를 통해서, Repository객체 주입
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);

}

//테스트 용도

public MemberRepository getMemberRepository() {
return memberRepository;
}
}


App.config내용

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;

public class AppConfig {

//단축키 : ctrl + alt + m : 중복제거

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

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

}
@Bean
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
}

@Bean
public DiscountPolicy discountPolicy() {
//여기만 바꾸면 객체들 가다 갈아끼울 수 있다.
//단축키 ctrl + R : 이전에 실행했던거 실행해준다.
return new RateDiscountPolicy();
}
}



이해가 가지않습니다..ㅠㅠ

 

 

답변 2

3

김영한님의 프로필 이미지
김영한
지식공유자

2022. 04. 02. 14:00

안녕하세요. 깨위님^^

섹션5. 싱글톤 컨테이너를 복습해주세요^^!

정답은 @Configuration이 필요합니다.

감사합니다.

1

정경훈님의 프로필 이미지

2022. 12. 07. 13:33

저도 값이 달라서 찾아봤는데... 저 같은 경우에는 Appconfig 파일에 @Configuration을 @Configurable 으로 잘못 넣고 있었네요....

깨위님의 프로필 이미지

작성한 질문수

질문하기