Annotation 은 metadata 라고 볼수 있습니다. 컴파일 과정과 런타임 과정에서 코드를 어떻게 컴파일하고 처리할 것인지를 알려주는 정보입니다. 사실 이러한 기능을 이용해서 생각보다 재미있는 기능들을 이용할 수 있기에 직접만들어보고, 이해되지 않았던 부분들을 정리했다.
사실 간단히 개념만 짚고 넘어가면 어디에 쓰이는지 잘모른다. 직접 해보는게 중요!
@Retention
: 어느 시점까지 어노테이션이 영향을 미치는지 결정 (Scope 라고 생각하면 쉬움)@Documentation
: 문서에도 어노테이션의 정보가 표현됩니다.@Target
: 어노테이션이 적용될 위치를 결정합니다.@Inherited
: 해당 어노테이션을 선언하면 부모 클래스에서 어노테이션을 상속 가능함.@Repeatable
: 반복적으로 어노테이션을 선언할 수 있게 합니다.data = 10
이라고 적으면 int 형 필드에 10을 주입시켜주는것.일단 인터페이스를 설계해보자
필드가 Target 이고 RUNTIME 동안 유지되야 하니깐..
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface InsertIntData {
int data() default 0;
}
자 일단 어노테이션은 이정도로 설계 해두면 될것 같다.
이제 주입을 어떤 시나리오로 할건지 생성하자
public class Example {
@InsertIntData(data = 30)
private int data;
public Integer getInject() {
return data;
}
}
import java.lang.reflect.InvocationTargetException;
public class Main {
public static void main(String[] args) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
CustomContextContainer customContextContainer = new CustomContextContainer();
//Example data = 30;
Example example = customContextContainer.get(Example.class);
System.out.println(example.getInject());
}
}
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
public class CustomContextContainer {
private <T> T invokeAnnotation(T instance) throws IllegalAccessException {
Field[] fields = instance.getClass().getDeclaredFields();
for(Field field : fields) {
InsertIntData annotation = field.getAnnotation(InsertIntData.class);
if(annotation != null && field.getType() == int.class) {
field.setAccessible(true);
field.set(instance, annotation.data());
}
}
return instance;
}
public <T> T get(Class<T> obj) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
T instance = obj.getDeclaredConstructor().newInstance();
instance = invokeAnnotation(instance);
return instance;
}
}
리플렉션 공부하고싶지만... 밀린 공부가 많아서 우선순위 큐에서 약간 밀렸네요.
꼭 공부해봐야겠어요!