[인프런 워밍업 스터디 클럽] 백엔드 과제1
[질문]
어노테이션을 사용하는 이유 (효과) 는 무엇일까?
- 코드량이 감소하고 유지보수하기 쉬우며, 생산성이 증가한다.
나만의 어노테이션은 어떻게 만들 수 있을까?
[ 커스텀 어노테이션 만들기 ]
예를 들어 다음과 같은 RestMemberController를 개발하여 Swagger로 문서화한다고 하자. 여기서 @Api와 @RestController 어노테이션은 다른 RestController들에도 공통적으로 적용되는데, 이를 커스텀 어노테이션으로 만들어 반복 작업을 줄여보도록 하자.
@Api
@RestController
@RequiredArgsConstructor
@RequestMapping("/member")
public class RestMemberController {
private final MemberService memberService;
@ApiOperation("멤버 목록 반환")
@GetMapping("/list")
public ResponseEntity<String> upload() {
return ResponseEntity.ok(memberService.getList());
}
}
1. 어노테이션 생성
어노테이션은 다음과 같이 인터페이스 앞에 @를 붙여서 생성할 수 있다.
public @interface RestControllerWithSwagger {
}
위와 같이 생성된 어노테이션은 다른 곳에서 참조되지만 아무런 기능도 하지 않는다.
2. 메타 어노테이션 추가
앞서 다른 어노테이션에 적용되기 위한 메타 어토네이션에 대해 살펴보았다. 그 중에서 필요한 것들을 적용하면 된다.
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@Target(ElementType.TYPE)
public @interface RestControllerWithSwagger {
}
위의 예제에서는 컴파일 이후에도 JVM에 의해 계속 참조가 가능하도록 @Retention(RetentionPolicy.RUNTIME) 을 적용하였으며, 하위 클래스에도 적용가능하도록 @Inherited를 적용하였다. 또한 javadoc에 의해 문서화가 되도록 @Documented를 적용하였으며, 타입 선언 시 어노테이션을 적용할 수 있도록 @Target(ElementType.TYPE)를 적용하였다. 여러 타겟을 원하는 경우에는 @Target({ElementType.TYPE, ElementType.Field}) 와 같이 사용하면 된다.
3. 적용할 어노테이션 추가
추가적으로 적용할 어노테이션이 있으면 추가해준다. 우리는 @Api와 @RestController라는 어노테이션을 공통으로 묶을 것이므로 이를 추가해준다.
@Api
@RestController
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@Target(ElementType.TYPE)
public @interface RestControllerWithSwagger {
String name() default "RestController";
String value();
}
4. 변수 추가
어노테이션에 값을 부여하기를 원한다면 변수를 다음과 같이 선언해줄 수 있다.
@Api
@RestController
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@Target(ElementType.TYPE)
public @interface RestControllerWithSwagger {
String name() default "RestController";
String value();
}
5. 적용하기
위와 같은 과정으로 어노테이션을 생성하였으면 이제 다음과 같이 적용할 수 있다.
@RestControllerWithSwagger(value = "RestMemberController", name = "RestMemberController")
@RequiredArgsConstructor
@Test1
@RequestMapping("/member")
public class RestMemberController {
private final MemberService memberService;
@ApiOperation("멤버 목록 반환")
@GetMapping("/list")
public ResponseEntity<String> upload() {
return ResponseEntity.ok(memberService.getList());
}
}
출처: https://mangkyu.tistory.com/130 [MangKyu's Diary:티스토리]