자바 커스텀 어노테이션은 주석(메타데이터)를 제공하는 목적으로 많이 씀.
더불어 java reflection 기능 활용하여 프레임워크단에서 기능 구현하기 위해서도 사용함.
@Retention(RetentionPolicy.RUNTIME) // 자바 바이트코드를 런타임에서 읽었을 때도 annotation 값을 삭제하지 않고 유지시킴
@Target({ElementType.TYPE, ElementType.FIELD}) // 어노테이션을 붙일 수 있는 위치를 한정 가능
@Inherited // 어노테이션을 붙인 클래스를 상속했을 때, 자식 클래스에도 어노테이션 적용되도록 하는 옵션
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.FIELD})
@Inherited
public @interface myAnnotation {
String value() default "yb";
int number() default 100;
}
아래는 reflection 기술로 특정 클래스에 붙은 annotation 중 원하는 것을 특정해서, 그 어노테이션의 엘리멘탈 값을 출력하는 코드.
@myAnnotation
public class Moja {
@myAnnotation
String aa;
public String pullOut(){
return "";
}
}
아래 로직은 특정 Class를 지정하고, 그 Class안의 Field 상위에 붙어 있는 annotation 리스트를 가져온 다음, 내가 찾은 annotation이 있으면 해당 annotation의 값을 가져오는 로직을 수행한다.
이 코드 아래 이미지에 스프링의 @GetMapping 어노테이션 예시를 보면, @GetMapping(name="/asdas") 처럼 입력하였을때, @GetMapping 어노테이션의 name 필드(용어가 맞는지는 모르겠음)에 연결할 URL 저장하면, 스프링 프레임워크에서 해당하는 URL 호출이 되었을 때 실행을 시켜주는 로직으로 동작하지 않을까 생각됨.
public class Masulsa {
public static void main(String[] args){
// // 바이트코드를 변경하는 뒷 작업 수행
// try {
// new ByteBuddy().redefine(Moja.class)
// .method(named("pullOut")).intercept(FixedValue.value("Rabbit!"))
// .make().saveIn(new File("C:\\code_folder\\clone_coding\\classloadersample\\target\\classes\\"));
// } catch (IOException e) {
// e.printStackTrace();
// }
// System.out.println();
// //System.out.println(new Moja().pullOut());
Arrays.stream(Moja.class.getDeclaredFields()).forEach(f->{
Arrays.stream(f.getAnnotations()).forEach(a->{
if(a instanceof myAnnotation) {
myAnnotation myAnnotation = (org.example.bytecode.myAnnotation) a;
System.out.println(myAnnotation.number());
System.out.println(myAnnotation.value());
}
});
});
}
}
아래는 스프링부트의 @GetMapping 어노테이션 파일 , URL을 입력받는 엘리멘탈 값으로 name, value 정의되어 있는 것 확인 가능함.
댓글