Programming/Spring framework

자동의존의 대상이 되는 클래스가 자손클래스일때, @Autowired 사용시 에러 처리법. 2021-06-01

최동훈1 2021. 6. 1. 17:22

우선 만약 이전 포스트에서는 @Autowired를 붙여서 자동의존주입을 하고자 하는 클래스의 타입이 빈 객체에 등록된 타입을 스프링이 탐색했을때, 1개로 특정지어지지 않을 경우 스프링은 에러를 낸다고 배웠다. 이번엔 쫌 다른 경우인데,

만약 스프링 빈에 등록할 객체가 이미 등록되어있는 빈 객체를 상속받은 클래스타입이라면 어떻게 될까?

예를 들어보자.

public class MemberSummaryPrinter extends MemberPrinter {

	@Override
	public void print(Member member) {
		System.out.printf(
				"회원 정보: 이메일=%s, 이름=%s\n", 
				member.getEmail(), member.getName());
	}

}

만약 이렇게 이미 빈 객체에 등록된 MemberPrinter 클래스를 상속받은 MemberSummaryPrinter라는 타입의 클래스를 빈 객체에 등록해보자.

	@Bean
	public MemberPrinter memberPrinter1() {
		return new MemberPrinter();
	}
	
	@Bean
	public MemberSummaryPrinter memberPrinter2() {//이 클래스타입은
    //MemberPrinter를 상속받은 클래스 타입임.
		return new MemberSummaryPrinter();
	}

이럴 경우에 만약 다른 클래스에서 @Autowired로 MemberPrinter 클래스 타입을 자동의존주입하려 했을때, 앞 포스트에서 설명한 에러인

No qualifying been of type 'spring.MemberPrinter' available: expected single matching been but found 2:memberPrinter1,memberPrinter2

이런 해당 타입의 빈이 한개가 아닌 두개라는 에러가 뜬다.

당연한 것이, 자바의 기본문법을 어느정도 숙지했다면,  자바 다형성의 특성에 의해 MemberSummaryPrinter타입의 객체를 조상타입인 MemberPrinter 참조변수로도 참조할수 있기 때문이다. 즉, @Autowired는 '타입'만 두고  어느 빈 객체를 자동의존주입시킬지 판별하기 떄문에 이런 일이 일어나는 것이다.

 

이런 상속받은 타입의 빈객체를 DI 할때 오류를 방지하는 2가지 방법이 있다.

이전 공부내용을  잘 숙지했다면 당연스레 해답을 떠올릴 수 있을 것이다.

첫번째는 @Qualifier를 통해 각각의 한정자를 만들고, @Autowired를 사용할때 @Qualifier도 써서 같이 쓰일수 있도록 하는 것이다.

	@Bean
	@Qualifier("printer")
	public MemberPrinter memberPrinter1() {
		return new MemberPrinter();
	}
	
	@Bean
	@Qualifier("summaryPrinter")
	public MemberSummaryPrinter memberPrinter2() {
		return new MemberSummaryPrinter();
	}

 두번째는, 

애초에 사용하는 @Autowired로 등록할 타입을 "MemberSummaryPrinter"로 지정해버리는 것이다. 애초에 자손클래스 타입으로만 DI할 빈 객체 타입을 등록해 버리면, 타입이 일치하는 빈 객체는 자손타입밖에 없기 때문이다.

 

*다형성 : 조상클래스의 참조변수로, 자손클래스의 객체를 참조하는 것.->리모콘의 버튼원리, 자바의 정석에서는 이와같이 비유했음. 참조변수는 리모콘의 버튼이고, 실제 객체는 TV이다. 리모콘에 누를수 있는 버튼이 있더라도, 잘못누르지만 않으면, 오류가 나지 않지만(업캐스팅), 만약 버튼이 없지만 누르려 하면 오류가 날 수밖에 없다.(다운캐스팅).

 

page 121 공부완료.

순공부 시간: 30분.

 

오늘 병가라서 집에서 쉬느라 잠을 쫌 잔거 같다. 요새 매일매일 헬스하느라 몸이 너무 힘들었는데, 고생한 '나'에게 휴식시간을 준 거 같아서 좋다.