@ReflectionHint란?
@ReflectionHint는 Spring Boot 3.x + AOT + Native 이미지 환경에서 아주 중요한 개념. 특히 GraalVM Native 이미지를 만들 때 리플렉션이 자동으로 안 되기 때문에, 리플렉션이 필요한 클래스들을 명시적으로 등록해주는 역할을 합니다.
✅ @ReflectionHint란?
Spring AOT에서 사용하는 애노테이션으로,
리플렉션을 사용하는 클래스나 멤버(생성자, 필드, 메서드 등) 를 native 이미지에 포함시키기 위해 힌트를 제공하는 도구입니다.
GraalVM Native 이미지에서는 리플렉션을 사용하려면 미리 등록해야 하기 때문에, 이 힌트가 필수입니다.
🔧 사용 예시
import org.springframework.aot.hint.annotation.ReflectionHint;
import org.springframework.aot.hint.annotation.TypeHint;
@ReflectionHint(
types = @TypeHint(types = MyClass.class)
)
public class MyAotConfig {
}
혹은 Spring Bean 클래스에 직접 적용할 수도 있어요:
@ReflectionHint(
types = @TypeHint(types = MyCustomDto.class, access = { TypeAccess.DECLARED_METHODS, TypeAccess.DECLARED_FIELDS })
)
public class MyService {
// ...
}
🧠 GraalVM에서 왜 필요한가?
자바의 리플렉션 API (Class.forName(), newInstance(), etc.) 는
런타임에 클래스를 찾아서 동적으로 객체를 생성합니다.
하지만 GraalVM Native 이미지 빌드 시에는 모든 코드를 정적 분석하므로,
리플렉션 대상 클래스를 미리 등록하지 않으면 런타임에 오류가 발생합니다.
java.lang.ClassNotFoundException: com.example.MyCustomDto
이런 오류가 날 경우, @ReflectionHint로 등록해줘야 합니다.
🔍 예시: DTO에 리플렉션 힌트 주기
@ReflectionHint(
types = @TypeHint(
types = MyDto.class,
access = { TypeAccess.PUBLIC_CONSTRUCTORS, TypeAccess.PUBLIC_FIELDS }
)
)
public class MyDtoConfig {
}
💡 팁: 자동 등록도 가능
Spring Boot 3.x에서는 다음처럼 자동으로 리플렉션 힌트를 등록할 수 있어요:
- @ConfigurationProperties 클래스
- @RestController에서 사용하는 DTO
- Jackson ObjectMapper 사용 시
하지만 동적 클래스 로딩이나 커스텀 리플렉션 사용 시에는 직접 @ReflectionHint를 써야 해요.
📦 대안: JSON 설정도 가능
reflect-config.json 파일을 생성해 직접 등록할 수도 있습니다 (Spring Native 이전 방식):
[
{
"name": "com.example.MyDto",
"allDeclaredConstructors": true,
"allDeclaredFields": true
}
]
그러나 Spring Boot 3.x에서는 @ReflectionHint를 사용하는 것이 더 깔끔하고 타입 안정적이에요.
📝 요약
항목 | 설명 |
역할 | 리플렉션 대상 클래스를 Native 이미지에 등록 |
사용 시점 | AOT & GraalVM Native 빌드 시 |
위치 | 클래스, Bean, 설정 클래스 등에 사용 |
대체 방식 | reflect-config.json 수동 작성 |