리플렉션과 어노테이션

최기곤·2021년 1월 14일
0

자바

목록 보기
2/3

Reflection

런타임시에 동작을 검사하거나 수정하는 것이다.
자바와 같은 정적언어에서 사용하면 컴파일 타임에 클래스의 정보를 구체적으로 알지 못해도 실행 중에 클래스에 접근할 수 있다.

Spring BeanFactory같은 곳에서 사용된다.

예시

public class ContainerService {
  public static <T> T getObject(Class<T> classType) {
    // 기본생성자를 통해서 인스턴스를 만든다.
    T instance = createInstance(classType);
    // 클래스의 모든 필드를 불러온다.
    Stream.of(classType.getDeclaredFields())
      .filter(field -> field.isAnnotationPresent(AutoWired.class)) // 어노테이션에 AutoWired를 갖는 필드만 필터
      .forEach(field -> {
        try {
          // 필드의 인스턴스 생성
          Object fieldInstance = createInstance(field.getType());
          // 필드의 접근제어자가 private인 경우 수정가능하게 설정
          field.setAccessible(true);
          // 인스턴스에 생성된 필드 주입
          field.set(instance, fieldInstance);
        } catch (IllegalAccessException e) {
          throw new RuntimeException(e);
        }
      });
    return instance;
  }
  private static <T> T createInstance(final Class<T> classType) {
    try {
      // 해당 클래스 타입의 기본생성자로 인스턴스 생성
      return classType.getConstructor().newInstance();
    } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
      throw new RuntimeException(e);
    }
  }
}

어노테이션

  • @Retention : 어노테이션의 범위로 어떤 시점까지 어노테이션이 영향을 미치는지 결정
    Type : SOURCE ,CLASS, RUNTIME
  • @Target : 어노테이션 적용할 위치
    TYPE : FIELT, METHOD, PARAMETER, CONSTRUCTOR등
  • @Inherited : 자식 클래스가 어노테이션을 상속

리플렉션 사용법

  • 리플렉션의 시작은 항상 Class<T> 에서 시작된다.

접근 방법

  1. "className.class"
  2. "인스턴스.getClass()"
  3. Class.ForName("classPath+클래스명")
  • getAnnotations : 상속받은 어노테이션까지 조회
  • getDeclaredAnnotations : 자기자신에게 붙어있는 어노테이션만 조회
profile
놀면서 일하고 일하면서 놀고~ 해삐~

0개의 댓글