Java
Java annotation(2) - Custom Annotation
구티맨
2022. 4. 1. 16:20
목차
사용자 정의 어노테이션을 정의하여, 특정 메소드에 정의한 어노테이션을 선언하고
이 어노테이션이 정의 되어 있는 메소드를 찾아 메소드 이름을 출력하는 스프링부트 프로그램을 작성해보겠습니다.
Annotation 정의
@interface를 사용하여 Print 어노테이션을 정의합니다.
어노테이션에 3개의 element를 정의합니다.
메소드에 적용 및 런타임에 사용하기 위해 Retention과 Target을 선언합니다.
package com.example.anno.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(value = ElementType.METHOD)
public @interface Print {
String value() default "";
String name();
String[] alias();
}
Annotation 사용
bark 메소드에 Print 어노테이션을 선언하며, element의 값을 설정합니다.
@Component
public class Dog {
@Print(value = "test", name = "doggy", alias = {"bom","bum"})
public void bark(){
System.out.println("Dog barked ---");
}
}
Annotation 처리 코드 작성
Dog 클래스의 선언된 메소드 중에 Print 어노테이션의 선언되어있는 함수가 있으면 메소드의 이름을 출력해주고,
어노테이션의 Element 값을 출력해줍니다.
@Component
public class MyApplicationRunner implements ApplicationRunner {
Dog dog;
public MyApplicationRunner(Dog dog) {
this.dog = dog;
}
@Override
public void run(ApplicationArguments args) throws Exception {
for(Method method : dog.getClass().getDeclaredMethods()){
if(method.isAnnotationPresent(Print.class)){
System.out.println("annotated method : " + method.getName());
Print annotation = method.getAnnotation(Print.class);
System.out.println("value : " + annotation.value() + ", name : " + annotation.name() + ", alias : " + Arrays.toString(annotation.alias()));
}
}
}
}
어노테이션 정의시에 사용되었던 Retention과 Target에 대해 자세히 알아보도록 하겠습니다.
Retention
어노테이션이 언제까지 유효한지를 명시합니다.
- SOURCE : 컴파일러에 의해 사라지는 어노테이션으로 CLASS파일에 저장되지 않고 source상에서만 확인이 가능하여 주석 같은 용도로 사용합니다.
- CLASS( Default ) : 컴파일러에 의해 CLASS 파일에 저장은 되지만, 런타임에는 유효하지 않습니다.
- RUNTIME : 런타임에도 유효합니다.
Target
어노테이션을 JAVA의 어떤 엘레멘트에 적용할지 명시합니다.
총 11가지의 엘레먼트 타입이 있으며, 아래 몇 가지만 소개를 하겠습니다.
- TYPE : 모든 타입에 사용 가능( ex. class, interface, enum, annotation )
- METHOD : 메서드에 사용 가능
- FIELD : 필드에 사용 가능
- CONSTRUCTOR : 생성자에 적용
- ANNOTATION_TYPE : 다른 어노테이션에 적용하기 위해 사용되는 타입.( ex @Target, @Retetion )
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
/**
* Declares whether the annotated dependency is required.
* <p>Defaults to {@code true}.
*/
boolean required() default true;
}
마지막으로 Spring Boot에서 많이 사용하는 Autowired라는 어노테이션을 보면,
런타임에 유효하고, 생성자, 메소드, 파라미터, 필드 그리고 다른 어노테이션에 적용을 할 수 있으며 required라는 엘레멘트를 가진다는 것을 알 수 있습니다.