이전포스트 내용에 이어서..
public class FixDiscountPolicy implements DiscountPolicy{
...
public class RateDiscountPolicy implements DiscountPolicy{
...
RateDiscountPolicy
와 FixDiscountPolicy
는 DiscountPolicy
를 implements 하고있으니 DiscountPolicy
를 불러올때마다 타입중복의 문제가 발생하는데 그때 해결책중 하나가 @Qualifier
를 써서 명시적으로 누굴 불러올건지 지정해주는것이다.
근데 @Qualifier
를 쓰면 가장 큰 문제점이.. 귀.찮.다!
@Component
@Qualifier("RateDiscountPolicy")
public class RateDiscountPolicy implements DiscountPolicy{
...
@Component
public class OrderServiceImpl implements OrderService{
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
public OrderServiceImpl(MemberRepository memberRepository, @Qualifier("RateDiscountPolicy") DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
...
매번 매핑을 해줄때마다 DI해주는곳이랑 구현체에 정의를해줘야하는데 그것도 손수 써야하니까 여간 귀찮은일이 아니다! 개발자에게 귀찮음은 숙적이자 능률인것.. 이것을 해결하기위해 어노테이션을 커스텀하여 일을 줄일수있다!
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Qualifier {
String value() default "";
}
이건 정의된 @Qualifier
인데 어노테이션의 구성을 살펴보자면?
@Target({ElementType.FIELD,
ElementType.METHOD,
ElementType.PARAMETER,
ElementType.TYPE,
ElementType.ANNOTATION_TYPE}): 이 어노테이션은 필드, 메서드, 파라미터, 타입, 어노테이션 타입에 적용될 수 있다.
@Retention(RetentionPolicy.RUNTIME): 이 어노테이션의 정보를 유지할 기간을 나타내는데 RUNTIME까지 유지되도록 설정되어있음
@Inherited: 이 어노테이션은 어노테이션이 자식 클래스에 상속되는지 여부를 나타낸다. 즉, 어떤 클래스에 어노테이션이 적용되어 있고 해당 클래스의 하위 클래스가 존재할 때, 하위 클래스에도 어노테이션이 상속되는지를 결정한다.
@Documented: Javadoc 도구를 통해 어노테이션 정보를 문서화하도록 지정한다. Javadoc에서 해당 어노테이션을 설명하는 데 사용된다. 즉, 코드를 문서화할 때 해당 어노테이션에 대한 정보도 함께 문서에 표시된다.
일반적으로 @Target
과 Retention
은 있어야함! 더 자세한건 어노테이션의 구성과 동작에 대한 원리에 대한 내용이니까 검색해보도록~
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@Qualifier("mainDiscountPolicy")
public @interface MainDiscountPolicy {
}
어노테이션을 커스텀하기위해 인터페이스를 생성하고 앞에 @를 붙인 뒤 @Qualifier
로 이름을 지정해주면된다!
@MainDiscountPolicy
public class RateDiscountPolicy implements DiscountPolicy{
...
public class OrderServiceImpl implements OrderService{
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
public OrderServiceImpl(MemberRepository memberRepository, @MainDiscountPolicy DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
...
}
이렇게하면 막 길게 안써도 되죠? 좀 줄어들었죠??
심심하면 어노테이션에 마우스대고 ctrl 좌클릭 습관화하기~