홈 › 고급 › 08 / 10

어노테이션·리플렉션·동적 프록시

Spring 과 MyBatis 가 움직이는 원리
섹션 7진행 0 / 10

5. 자주 하는 실수 (Tip)

  1. @Retention(RUNTIME) 누락. 기본값 CLASS 면 getAnnotation 이 항상 null 입니다. 예외도 없어서 "왜 안 읽히지" 로 한참 헤맵니다.

  2. 같은 클래스 안 내부 호출. this.transfer() 는 프록시를 거치지 않습니다. @Transactional, @Cacheable, @Async 모두 같은 이유로 무시됩니다.

  3. private 메서드에 @Transactional. CGLIB 는 하위 클래스를 만드는 방식이라 private 메서드를 덮어쓸 수 없습니다. 어노테이션이 조용히 무시되며, 아무 경고도 없습니다.

  4. InvocationTargetException 을 그대로 던짐. 원본 예외가 감싸져 상위 catch (IllegalStateException) 이 잡지 못합니다. 프록시 핸들러에서는 getCause() 를 다시 던집니다.

  5. Long.class 로 long 메서드 찾기. 리플렉션은 오토박싱을 모릅니다. 시그니처의 원시 타입은 long.class, int.class 로 정확히 지정합니다.

  6. @Param 없이 인자 두 개. #{id} 가 arg0 을 찾지 못해 바인딩 오류가 납니다. 인자가 둘 이상이면 @Param 을 붙이거나 -parameters 로 컴파일합니다.

  7. 리플렉션을 루프 안에서 매번 조회. getMethod 는 느립니다. 한 번 찾은 Method·Field 는 필드나 캐시에 보관하고 재사용합니다.

  8. getDeclaredMethods() 순서에 의존. JVM 마다, 실행마다 순서가 다를 수 있습니다. 순서가 필요하면 정렬하거나 어노테이션에 order 속성을 둡니다.