본문 바로가기

Backend/SpringBoot

Spring Boot Custom Annotation 만들기

안녕하세요!

이번 포스팅에서는 Spring Boot에서 Custom Annotation을 만드는 방법에 대해 알아보겠습니다.

전체 코드는 Github에서 확인이 가능합니다. ✍️


📚 개념 정리

1. 커스텀 어노테이션이란?

프로그램에 관한 데이터를 제공하거나 코드에 정보를 추가할 때 사용하는 것을 어노테이션이라고 합니다. 대표적인 어노테이션으로는 @Controller, @SpringBootApplication등이 있습니다.

하지만 위 예시 어노테이션들은 이미 만들어진 어노테이션들이고, 직접 커스텀해서 어노테이션을 만들 수 있는데, 이것을 커스텀 어노테이션이라고 합니다.

2. 프로젝트 설명

이번 프로젝트는 예전에 AOP를 사용해서 모든 요청/응답에 로그를 적용한 프로젝트에서 특정 메소드에는 로깅에서 제외하는 커스텀 어노테이션을 만들어보도록 하겠습니다.


💻 구현

1. 커스텀 어노테이션 만들기

LogExclusion.java

@Target({ElementType.METHOD}) // 1
@Retention(RetentionPolicy.RUNTIME) // 2
public @interface LogExclusion {

}

먼저 @interface를 추가하여 어노테이션으로 만들어줍니다.

① @Target

   - 어노테이션이 생성될 수 있는 위치를 지정하는 어노테이션입니다.

   - 로그를 제외하는 어노테이션은 메소드 위에 선언하기 때문에 METHOD로 지정해주었습니다.

 

② @Retention

    - 어노테이션이 언제까지 유효할지 정하는 어노테이션입니다.

    - 실행 동안은 계속 유효해야하기 때문에 RUNTIME으로 지정해주었습니다.

앞으로 이 어노테이션을 사용하려면 메소드 위에 @LogExclusion을 추가해주면 됩니다.

 

2. LogConfig 수정하기

전체 코드가 궁금하신 분은 전 포스팅을 참고해주세요!

LogConfig.java

@Slf4j
@Component
@Aspect
public class LogConfig {

  @Around("within(me.shinsunyoung.aop.controller..*) && !@annotation(me.shinsunyoung.aop.config.LogExclusion)")
  public Object logging(ProceedingJoinPoint pjp) throws Throwable { 

    ...
  }

 ...

}

기존에는 controller 패키지 안에 있는 메소드에 모두 aop를 적용했다면,

@LogExclusion 어노테이션이 붙은 것은 aop를 적용하지 않게 추가로 설정해줍니다.

 

3. 어노테이션 붙이고 테스트하기

TestController.java

@RestController
public class TestController {

  ...

  @GetMapping("/test1")
  public void test1(){
    System.out.println("TEST1");
  }

  @LogExclusion // 로깅 제외
  @GetMapping("/test2")
  public void test2(){
    System.out.println("TEST2");
  }

}

메소드를 두 개 만들어서 첫 번째 메소드는 로그가 나오게,

두 번째 메소드는 로그가 나오지 않게 설정해줍니다.

그 후에 제대로 적용이 되었나 테스트해보겠습니다.

http://localhost:8080/test1

http://localhost:8080/test2

를 순서대로 접속한 후에 로그가 찍힌 부분을 확인합니다.

어노테이션을 붙이지 않은 메소드는 AOP가 적용되어서 로그가 잘 나오지만,

어노테이션을 붙인 메소드는 AOP가 적용되지 않기 때문에 로그가 나오지 않는 것을 확인할 수 있습니다.

현재 예제에서는 단순히 마킹을 해두는 역할의 어노테이션을 만들었지만,

값을 넘겨주거나 확인할 수 있는 어노테이션 역시 커스텀 하여 만들 수 있습니다. (참고 항목)


⚠️ 주의사항

어노테이션을 사용하면 코드가 간결해지기 때문에, 자칫하면 커스텀 어노테이션을 남발할 수 있습니다. 을 읽다가 좋은 내용이 있어 내용을 발췌해왔습니다.

어노테이션의 의도는 숨어있기 때문에 내부적으로 어떤 동작을 하게 되는지 명확하지 않다면 로직 플로우를 이해하기 어렵게 되고, 코드정리가 덜 되어 현재 사용되지 않고 있는 어노테이션들이 있더라도 쉽사리 누군가가 손을 대기 부담스러워하는 경우도 왕왕 봐왔습니다. 하물며 ‘커스텀’ 어노테이션은 그 부담을 가중시킵니다. 무분별한 어노테이션 추가가 당장의 작업 속도를 끌어올릴 순 있지만, 긴 관점에서 시의적절한 것인지를 공감할 수 있어야 합니다.

구성원간의 이해와 공감대가 선행돼야 합니다. 또한 커스텀 어노테이션은 플로우에 대한 컨텍스트를 담고 있기 때문에 용도와 목적에 맞게 작성하는 것이 중요합니다. 다른 말로, 이것 저것 할 수 있는 다기능으로 만들게 되면 해석이 어려워진다는 뜻입니다.

코드가 간결해진다는 장점 하나만 보고 어노테이션(특히 커스텀 어노테이션)을 남용하지 않게 주의해야하고, 어노테이션을 만들 때 이게 반드시 필요한 어노테이션이 맞는지 다시 한 번 확인하는 것도 중요한 것 같습니다.

혹시 글을 읽으면서 잘못된 내용이 있으면 댓글로 알려주시면 감사하겠습니다!

읽어주셔서 감사합니다! 😊


👏 참고

스프링부트와 AWS로 혼자 구현하는 웹서비스 5.4 어노테이션 기반으로 개선하기 (깃허브 코드)

시의적절한 커스텀 어노테이션 - 우아한형제들 기술 블로그

custom annotation 만들기