런타임 도중 코드를 조작하는 마법, 리플렉션

리플렉션 이해하기

리플렉션이란?


리플렉션

런타임에 클래스 로더에 의해 메모리에 로드된 클래스 정보를 통해 클래스의 구조(필드, 메서드, 생성자)를 분석하고 객체를 동적으로 생성하거나 메서드를 호출하는 기술이다.

이 리플렉션을 번역하면 반사 라고 직역이 되는데, 쉽게 이해를 돕기 위해 이 직역된 단어 "반사" 를 생각해보고 의미를 해석하면 이렇다.

JVM 이 동작할 때 클래스 로더가 바이트코드를 읽고 클래스의 정보를 메모리 영역에 할당하는 작업을 하게 되는데, 이 메모리 영역에 올라온 클래스 정보가 마치 사용자가 작성한 소스코드가 반사 되어 내부에 감춰진 속성들이 드러나게 되는 것이다.

이 의미를 이해한 뒤 리플렉션을 통해 얻는 이점을 살펴보자.

리플렉션을 통해 얻을 수 있는 이점

  1. 클래스의 명칭만 알고 있으면 클래스를 직접 조작할 수 있다.

  2. 클래스의 속성, 메서드, 생성자 등에 접근이 가능하고 접근제어자를 통해 감춰둔 요소들을 강제로 접근할 수 있다.

강력한 기능 만큼 강력한 단점도 존재한다


  1. 리플렉션을 사용하면 JVM 컴파일 단계에서 발생하는 예외를 지원받지 못한 채, 런타임에서 발견하게 된다.

  2. JVM 의 컴파일 시점에서 타입 검증을 통해 생성하는 방법과 달리 리플렉션은 런타임 중 클래스에 대한 분석이 필요하기 때문에 성능이 저하된다.

  3. 객체지향 프로그래밍의 특성인 캡슐화와 추상화를 깨트려, 유지보수가 힘든 코드를 생성할 수 있다.

리플렉션 사용 해보기


학습 테스트

스프링은 리플렉션을 어떻게 쓸까?

빈 객체 생성

아래 코드는 SpringFrameworkBeanUtils 추상 클래스이며, 클래스를 인스턴스화 하는 메서드에서 리플렉션을 잔뜩 사용하고 있는것을 볼 수 있다.

의존성 주입

Autowired 어노테이션을 사용하고 있는 메타데이터를 찾거나 캐쉬에서 검색하여 반환 받은 AutowiredElement 를 상속 받은 객체의 inject() 메서드를 호출하는 과정이다.

참고 자료

Last updated