Spring

TIL-5 @Autowired @Qualifier @Primary, 어노테이션 생성, 조회한 Bean을 모두 사용하고 싶을 경우

다오__ 2023. 5. 18. 18:48

@Autowired Type으로 조회한다.

Type으로 조회하기 때문에 다음 코드와 유사하게 동작한다 (실제로는 많은 기능을 제공한다.)

ac.getBean(DiscountPolicy.class)

 

조회 빈을 2개로 만들어 어떤 문제가 발생하는지 알아보자.

 

 

DiscountPolicy 인터페이스에 2개의(Fix, Rate) 구현체에 @Component 어노테이션을 달았다.

 

이제 @Autowired DiscountPolicy 주입 받을려고 하면 아래와 같은 충돌이 일어나게 된다.

기대한 값은 하나의 빈인데 발견한건 2개가 되어 어떤 매칭할지 정할 없어 생기는 컴파일 오류이다.

 

이때 주의할 점은 하위타입으로 지정하는 것인데 이렇게 하면 DIP 위배하고 유연성이 떨어진다. 그리고 이름은 다르지만 같은 타입의 스프링 빈이 2 있을 해결이 안된다.

 

스프링 빈을 수동 등록해서 문제를 해결해도 되지만, 이럴 해결하는 여러 방법이 있다.

 

1. @Autowired 필드  2. @Quilifier 3. @Primary

 

@Autowired 필드 매칭

 

@Autowired 처음에 Type매칭을 시도하고, 이때 여러 빈이 있으면 필드 이름, 파라미터 이름으로 이름을 추가 매칭한다.

 

생성자 주입할 때에 파라미터 이름으로 구별하게 시켜주면 해결 가능하다.

 

 

@Qualifier사용

 

@Qualifier추가 구분자를 붙여주는 방법이다. 주입 추가적인 방법을 제공하는 것이지 이름을 변경하는 것은 아니다.

 

' 등록시 @Quilifier 붙여 준다'

 

 

 

 

기존의 @Component 어노테이션 밑에 각각의 @Qualifier 붙혀 주었다 다음으로

 

 

 

생성자 주입 위와 같이 추가를 해주어 해결 있다.

 

 

 

@Primary 사용

@Primary는 우선순위를 정하는 방법이다. @Autowired시에 여러 매칭 되면 @Primary가 우선권을 가진다.

 

rateDiscountPolicy가 우선권을 가지도록 하자.

 

Ctrl alt b : 인터페이스에서 구현체로 바로 이동

 

단순하게 어노테이션만 붙이면 되기에 자주 사용하는 방법이다.

메인DB와 서브DB가 있는 경우

 

 

어노테이션 직접 만들기

@Qualifier("mainDiscountPolicy") 이렇게 문자를 적으면 컴파일 타입 체크가 안되어 컴파일 오류로 확인할 수가 없다.

 

다음과 같이 어노테이션을 직접 만들어 문제를 해결할 있다.

 

 

 

 

위와 같이 직접 만든 어노테이션을 사용 있다.

 

[Ctrl b : 해당 어노테이션을 사용한 파일들로 이동]

 

 

 

 

조회한 빈이 모두 필요할 List, Map

의도적으로 정말 Fix, Rate 스프링 빈이 필요한 경우도 있다.

예를들어 할인 서비스를 제공하는데 클라이언트가 종류를 선택할 있다고 가정해보면

스프링은 소위 말하는 전략 패턴을 매우 간단하게 구현할 있다.

 

테스트 클래스를 만들어 Map과 List로 DiscountPolicy를 담아보자

 

 

 

Map과 List에 정상적으로 담긴 것을 있다.

 

이를 활용해 할인금액을 리턴하는 메서드를 만들어 보자

 

전략패턴은 메뉴를 선택할 활용할 효율적이다.

동적으로 빈을 선택해야할 Map으로 받아 활용하면 다형성 코드를 유지하며 사용할 있다.