Java Reflection (리플렉션)

Jake·2022년 4월 10일
1

Java

목록 보기
8/8

1. What is Reflection

  • 클래스로더를 통해 읽어온 클래스 정보를 사용하는 기술
  • 클래스를 읽어오거나, 인스턴스를 만들거나, 메소드를 실행하거나, 필드의 값을 가져오거나 변경하는 것이 가능하다

출처 : 백기선님의 자바 리플렉션 유튜브 강의

  • 위 정의에 따르면, 처음 공부하는 입장에서는 리플렉션을 사용하는 이유가 잘 와닿지 않을 가능성이 높습니다.
  • 저의 경우에는 굳이 리플렉션이라는 기술을 써야하나? 라는 생각이 들었습니다.
  • 인스턴스를 만들어서 메서드도 실행하고 필드의 값을 가져오거나 변경하는 것이 일반적으로 자바에서 행하는 방식이기 때문입니다.

2. Why Reflection?

1_ 정적 언어의 한계

그렇다면 리플렉션은 왜 사용하는 것일까요? 바로 정적 언어인 자바의 한계를 극복하기 위해서입니다.

정적 언어의 한계는 무엇일까요?

  • 정적인 언어인 자바는 컴파일 단계에서 타입이 결정됩니다
  • 동적인 언어인 파이썬은 런타임 단계에서 타입이 결정됩니다

즉, 정적 언어인 자바의 한계는 런타임에서 타입을 결정할 수 없다는 것입니다.

2_ 정적 언어 한계를 극복한 스프링

  • 컴파일 단계에서 모든 타입을 결정해야 합니다. 즉, 코드에 타입에 대한 모든 내용이 작성되어 있어야 합니다.

  • Java 만으로는 객체지향을 지킬 수 없다는 것을 알아볼 때, 스프링의 역할에 대해 이렇게 설명한 적이 있습니다.

    스프링의 DI는 클래스 내부에 생성자를 두지 않아도 스프링이 런타임에 외부에서 객체를 생성해서 주입시켜 준다

  • 그렇다면 스프링은 어떻게 런타임에 객체를 외부에서 생성시켜 주입해주는 것일까요?

3_ 스프링에서는 어떻게 Reflection이 쓰였는가

스프링 DI는

  • 객체를 생성하고
  • 다양한 의존성 주입 방법을 통해 필드를 주입해줍니다

코드를 작성한 개발자는 클래스의 정보에 대해 알고 있지만, 스프링은 클래스 정보를 모릅니다.

  • 스프링은 하나의 프레임워크로, 우리가 스프링을 사용한다는 것의 의미는 이미 작성된 코드를 가져다 쓴다는 것과 마찬가지입니다.

  • 때문에 스프링은 개발자인 우리가 작성하는 코드에 대한 정보는 전혀 모르게 됩니다. 즉, 스프링은 런타임에 클래스 정보를 알아야 합니다.

  • 그렇기 때문에 클래스 로더를 통해 클래스 정보를 가져오고 그 정보를 토대로 어떤 값을 주입해야 하는지 판별하는 것입니다

이를 위해 스프링의 DI에서는 Reflection을 사용합니다.

4_ Filter에서의 Reflection

https://www.youtube.com/watch?v=AyQwvxRJ0q0 강의에서는 Dispatcher를 직접 코드로 구현하는 과정을 보여주시는데, 본 강의를 보다보면 왜 Reflection을 써야 하는지 더 확실하게 알 수 있습니다.

  • Reflection을 사용하지 않으면 url에 대한 if-else문을 작성해야 합니다.
  • 새로운 url이라도 생기는 날에는, Dispatcher의 코드 내부에 있는 if-else문을 변경해야 하는 불상사가 발생합니다.
  • 이를 방지하기 위해서는 클래스의 메서드를 탐색할 수 있는 방법이 있어야 하며, 이를 컴파일 시점이 아닌 런타임 시점에 알 수 있어야 합니다.

3. 그냥 컴파일 시점에 알면 안되는가?

  • 컴파일 시점에 안다는 것은, 코드에 그것을 작성하겠다는 의미입니다.
  • 코드로 작성한다는 것은, 구체화에 의존하게 된다는 의미입니다(의존관계 역전 원칙 위반).
  • 구체화에 의존하게 된다는 것은, 변경에 취약하게 된다는 의미입니다.
  • 변경에 취약하다는 것은 OCP를 지킬 수 없게 된다는 것입니다.

위에서 소개해드린 유튜브 영상에서 if-else문으로 만들어진 Dispatcher 코드를 보시며 이렇게 말씀하십니다.

"이런 코드 팔 수 있어요? 절대 못 팔아요. 누가 이걸 삽니까"

결국 이 말이 컴파일 시점에 모든 것을 결정하면 안되는 이유를 한 번에 압축한 말이 아닐까 싶습니다.

  • 팔 수 없다는 것은, 타인이 내 서비스를 이용하는 것이 불가능할 정도로 불편하다는 것입니다.
  • 오픈소스 목적이던, 상업족 용도이던, 내가 작성한 코드가 나만의 손이 아니라 세상에 보여질 수 있기 위해서는 특정 상황에서 정적 언어의 한계를 뛰어넘는 법을 알아야 할 것입니다.

공부에 도움이 되었던 링크

profile
Java/Spring Back-End Developer

0개의 댓글