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

kth9024님의 프로필 이미지

작성한 질문수

스프링 핵심 원리 - 기본편

@Autowired 필드 명, @Qualifier, @Primary

NoUniqueBeanDefinitionException 에러 ..

작성

·

380

0

학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.

1. 강의 내용과 관련된 질문을 남겨주세요.
2. 인프런의 질문 게시판과 자주 하는 질문(http://bit.ly/3fX6ygx)을 먼저 확인해주세요.
3. 질문 잘하기 메뉴얼(http://bit.ly/2UfeqCG)을 먼저 읽어주세요.

질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.
=========================================
[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? (예/아니오)


2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)

3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)

[질문 내용]
여기에 질문 내용을 남겨주세요.
안녕하세요 강사님 !
AutoAppConfigTest에서 OrderServiceImpl 에러가 발생해 문의드립니다 ㅠㅠ
OrderServiceImpl 생성자쪽에 print 찍고 실행해보니 ..
생성자가 두번 호출되어 bean이 두개생성되어 오류나는거 같은데 .. 왜 두번 호출되는지를 잘 모르겠네요 ..

아래는 AutoAppConfigTest랑 AutoAppConfig 코드입니다..

public class AutoAppConfigTest {
    @Test
    void basicScan(){
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AutoAppConfig.class);

        MemberService memberService = ac.getBean(MemberService.class);
        assertThat(memberService).isInstanceOf(MemberService.class);


        OrderServiceImpl bean = ac.getBean(OrderServiceImpl.class);
        MemberRepository memberRepository = bean.getMemberRepository();
        System.out.println("memberRepository = " + memberRepository);

    }
}

package hello.core;

import hello.core.discount.DiscountPolicy;
import hello.core.discount.RateDiscountPolicy;
import hello.core.member.MemberRepository;
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.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;

@Configuration
@ComponentScan (
        basePackages = "hello.core", //여기 패키지부터 스캔
        //basePackageClasses =
        //컴포넌트 스캔중 뺄거 지정 (지정하지 않을시 default 현재 @ComponentScan이 붙은 설정정보 클래스의 package)
        excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Configuration.class)
)
public class AutoAppConfig {
    @Bean(name = "memoryMemberRepository")
    MemberRepository memberRepository(){
        return new MemoryMemberRepository();
    }

    @Bean(name = "orderService")
    public OrderService orderService(){
        System.out.println("call AppConfig.orderService");
        return new OrderServiceImpl(memberRepository(), discountPolicy());
        //return null; ////필드주입
    }

    @Bean(name = "discountPolicy")
    public DiscountPolicy discountPolicy(){

        return new RateDiscountPolicy();
    }

}

답변 2

0

kth9024님의 프로필 이미지
kth9024
질문자

OrderService 인터페이스 

package hello.core.order;

public interface OrderService {
    Order createOrder(Long memberId, String itemName, int itemPrice);
}

OrderServiceImpl 클래스

package hello.core.order;

import hello.core.discount.DiscountPolicy;
import hello.core.discount.FixDiscountPolicy;
import hello.core.discount.RateDiscountPolicy;
import hello.core.member.Member;
import hello.core.member.MemberRepository;
import hello.core.member.MemoryMemberRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;


//@RequiredArgsConstructor //lombok 생성자주입 (final 붙은 필드를 가지고 생성자를 자동으로 만들어준다)
@Component
public class OrderServiceImpl implements OrderService{

    //필드주입
//    @Autowired private MemberRepository memberRepository;
//
//    @Autowired private DiscountPolicy discountPolicy;

    private final MemberRepository memberRepository;
    private final DiscountPolicy discountPolicy;

    //생성자 주입
    @Autowired // 생성자 1개일시 쓰지않아도 됨
    public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy rateDiscountPolicy) {
        System.out.println("생성자호출");
        this.memberRepository = memberRepository;
        this.discountPolicy = rateDiscountPolicy;
    }

    //수정자 주입
//    @Autowired
//    public void setMemberRepository(MemberRepository memberRepository){
//        this.memberRepository = memberRepository;
//    }
//
//    @Autowired
//    public void setDiscountPolicy(DiscountPolicy discountPolicy){
//        this.discountPolicy = discountPolicy;
//    }

    //메소드 주입입
//   @Autowired
//    public void init(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);
    }

    public MemberRepository getMemberRepository() {
        return memberRepository;
    }


}

AppConfig의 oderService() 의 반환타입을 OrderService가 아니라 OrderServiceImpl로 변경해보시겠어요?

아래 답변을 참고하시면 좋을 것 같습니다.

https://www.inflearn.com/questions/69229

0

안녕하세요. kth9024님, 공식 서포터즈 David입니다.

.
OrderService 클래스(또는 인터페이스) 코드 전체를 공유해주실 수 있으실까요?
.
감사합니다.

kth9024님의 프로필 이미지

작성한 질문수

질문하기