리플렉션

eunsiver·2023년 5월 1일
0

Spring boot 구현

목록 보기
9/12

스프링은 어떻게 실행시점에 빈을 주입할 수 있는 것일까?

JPA의 Entity는 왜 꼭 기본 생성자를 가져야 하는 것일까?

이는 리플렉션과 연관이 있다.


리플렉션이란

리플렉션을 우리 말로 번역하면
reflection : (거울 등에 비친) 상 [모습]

예> 우리는 거울을 보면서 머리를 정리하거나 옷 매무새를 다듬는다.

이렇게 실제가 아닌 반사, 반영된 이미지를 통해 어떤 행위를 하는 것을 리플렉션이라고 한다.


자바 세상에서는 무엇이 어디에 반사되어 있는것일까?

자바에서는 실체는 Class이고 거울은 JVM 메모리 영역이다.

자바에서는 컴파일러가 자바 코드를 바이트코드로 바꿔준다.
쿨래스 로드는 이 바이트코드를 읽어 JVM 내 메모리 영역에 저장하게 된다.

리플렉션은 이 JVM 메모리 영역에 저장된 클래스 정보를 꺼내와서 필요한 정보들 생성자, 필드, 메서드들을 가져와 사용하는 기술이다.


리플렉션 기능을 지원하지 않는 언어도 있다.

  • C, C++, Pascal

이들은 해당 프로그램 내에서 정의된 함수에 대한 정보를 가져올 수 없다.


리플렉션을 왜 쓸까?

리플렉션은 주로 프레임워크나 라이브러리에서 많이 사용된다.

직접 코딩을 할 때는 객체의 타입을 모르는 일은 거의 없다.

반면 프레임워크나 라이브러리에서는 사용자가 생성한 객체가 어떤 타입인지 컴파일 시점까지 알 수가 없다.

이러한 문제를 동적으로 해결하기 위해 리플렉션을 사용한다.


리플렉션이 사용되는 곳?

리플렉션이 사용되는 곳!

  • JPA, Jackson, Mockito, JUnit 등등,,,,

  • 인텔리제이의 자동 완성 기능도 리플렉션을 사용한 기능이다!!

  • 어노테이션에서도 리플렉션이 사용된다.


어노테이션은 그냥 주석인데 어떻게 동작하는 걸까?

  • 리플렉션을 통해 클래스나 메서드, 파라미터 정보를 가져온다.

  • 리플렉션의 getAnnotation(s), getDeclaredAnnotation(s) 등의 메서드를 통해 원하는 어노테이션이 붙어 있는지 확인한다.

  • 어노테이션이 붙어 있다면 원하는 로직을 수행한다.


리플렉션이 제공하는 기능들

리플렉션의 기본은 class

Class

  • Class는 실행 중인 자바 어플리케이션의 클래스와 인테페이스의 정보를 가진 클래스

  • public 생성자가 존재한지 않는다.
  • Class 객체는 JVM에 의해 자동으로 생성된다.

리플렉션의 기능

  • 생성을 통한 객체 생성

리플렉션을 이용하면 private 생성자에도 접근 할 수 있게 해준다.

접근제어자가 public이 아닌 경우 setAccessible 메서드를 이용하면 접근할 수 있다.

  • 필드 값 변경

리플렉션을 이용하면 private 필드의 값도 변경해줄 수 있다.


객체에 기본생성자가 필요한 이유

많은 프레임워크나 라이브러리에서 객체에 기본 생성자가 왜 필요할까?

JPA 엔티티, DTO에서 기본 생성자를 필요로 한다.

이 이유는 바로 리플렉션 때문!

그 이유는 기본 생성자로 객체를 생성하고 필드를 통해 값을 넣어주는 것이 가장 간단한 방법이기 때문이다!

기본생성자가 없다면
1. 생성자가 많은 경우 어떤 생성자를 사용할지 고르기 프레임워크나 라이브러리가 고르기 어렵다.
2.생성자에 로직이 있는 경우 원하는 값을 필드에 바로 넣어 줄 수 없다.
3. 파라미터들의 타입이 같은 경우 필드와 이름이 다르면 값을 알맞게 넣어주기 힘들다.


기본 생성자를 사용할 경우 이 모든 경우의 수를 고려하지 않아도 된다.

기본 생성자로 객체를 생성한 뒤, 필드 이름에 맞춰 알맞은 값을 넣어주면 된다.


리플렉션의 단점

  1. 일반 메서드 호출보다 성능이 훨씬 떨어진다.

Reflection API는 컴파일 시점이 아니라 런타임 시점에서 클래스를 분석한다.
--> JVM을 최적화 할 수 없기 때문에 성능저하 발생

  1. 컴파일 시점에서 타입 체크 기능을 사용할 수 없다.

    리플렉션은 런타임 시점에서 클래스 정보를 알게 된다.
    따라서 컴파일 시점에 제공하는 타입 체크 기능을 사용할 수 없게 된다.

    만약 존재하지 않는 클래스에 접근해 메서드를 호출하더라도 결국 ClassNotFoundException이라는 에러를 맞이 하게 된다.

  2. 코드가 지저분해지고 장황해진다.

  1. 내부를 노출해서 추상화를 파괴한다.

    리플렉션을 사용하면 접근할 수 없는 필드나 메서드에도 접근할 수 있고 모든 클래스의 정보를 알게 된다.

    추상화를 파괴하고 따라서 불변성 또한 지킬 수 없게 된다.


리플렉션은 아주 제한된 형태로만 사용해야 한다.

따라서 클래스의 정보를 컴파일 시점에 알아야 하는 특수한 경우가 아니라면 리플렉션 사용을 지양하고 꼭 필요한 경우에만 리플렉션을 사용하자!

profile
Let's study!

0개의 댓글