[Spring] 커스텀 어노테이션 만들기

이신영·2024년 1월 17일
1

Spring

목록 보기
9/16
post-thumbnail
post-custom-banner

쓰는 이유?

이전포스트 내용에 이어서..

public class FixDiscountPolicy implements DiscountPolicy{
	...
public class RateDiscountPolicy implements DiscountPolicy{
	...

RateDiscountPolicyFixDiscountPolicyDiscountPolicy를 implements 하고있으니 DiscountPolicy를 불러올때마다 타입중복의 문제가 발생하는데 그때 해결책중 하나가 @Qualifier를 써서 명시적으로 누굴 불러올건지 지정해주는것이다.

근데 @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에서 해당 어노테이션을 설명하는 데 사용된다. 즉, 코드를 문서화할 때 해당 어노테이션에 대한 정보도 함께 문서에 표시된다.

일반적으로 @TargetRetention은 있어야함! 더 자세한건 어노테이션의 구성과 동작에 대한 원리에 대한 내용이니까 검색해보도록~

@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 좌클릭 습관화하기~

profile
후회하지 않는 사람이 되자 🔥
post-custom-banner

0개의 댓글