리플랙션 활용하기

유수민·2024년 3월 25일
0
post-thumbnail
post-custom-banner

📌 개요

새로운 시니어 개발자가 들어왔당🎉
그때 들었던 말 중에 하나가

나랑 일하려면 리플랙션 알아야 행 ><

였다. 리플랙션? 그게 뭐였지? 그 동안 코드 상에서 리플랙션을 사용해본 적이 없어서 '뭐였더라? 예전에 어노테이션이랑 이런거 관련된 거 였는데' 정도만 생각하고 있었다.
이전에 내가 써놓은 이론적인 내용을 찾아보니 >> Object와 Reflection

리플렉션은 구체적인 클래스 타입을 알지 못해도, 그 클래스의 메소드, 타입, 변수들에 접근할 수 있도록 해주는 자바 API이다. 프로그램이 동적으로 소스 코드를 해석하여 클래스의 정보를 분석해 내는 기술

이라고 써져 있었다. 취준 기간에는 단순히 어떤 것인지 알아보았다면 이번에는 실무에서 얼마나 활용하는지 확인해보려고 한다.

📌 리플랙션을 통해 가져올 수 있는 것

간단히 리플랙션을 통해 알 수 있는 정보를 정리해보자면,

  • getXXX() : 상속받은 클래스와 인터페이스를 포함하여 모든 public 요소를 가져온다.
  • getDeclaredXXX() : 상속받은 클래스와 인터페이스를 제외하고 해당 클래스에 직접 정의된 내용만 가져온다. 또한 접근 제어자와 상관없이 요소에 접근할 수 있다
    👉 메소드, 필드, 어노테이션 다 가져올 수 있다는 말
  1. Class 객체를 획득 할 수 있다.
  2. Class 를 사용해서 생성자를 Constructor 타입으로 가져올 수 있다
  3. 필드 (목록) 가져올 수 있다 : 리플렉션을 사용하여 Field 타입의 오브젝트를 획득하여 객체 필드에 직접 접근할 수 있다.객체의 필드값에 접근하여 값을 수정 할 수도 있다.
  4. 메소드 (목록) 가져져올 수 있다 : 리플렉션을 사용하여 Method 타입의 오브젝트를 획득하여 객체 메소드에 직접 접근할 수 있다
  5. 어노테이션에 대한 정보 가져올 수 있다 : 클래스에 붙어있는 어노테이션을 가져올 수 있다. 어노테이션이 가지고 있는 필드에도 접근할 수 있다.

이렇게만 알면 잘 와닿지가 않는다.
생각해보면 내가 가장 궁금했던 것은 진짜 이걸 실무에서도 쓰긴 하는 거야? 어떻게 활용하는 거야? 였다.

📌 리플랙션의 활용

결론은 은근히 사용했다. 경험이 쌓이면 더 많이 사용하는 모습이 보일 것 같다.
내가 찾은 활용도는
1) 어노테이션
자신의 어노테이션을 만들고, 해당 어노테이션이 선언되어 있는 클래스가 있다.

만약 해당 어노테이션이 선언된 클래스들을 모아다가 같은 비지니스 로직을 행하게 하고 싶으면?

  • metadata.getEntityBindings(): 데이터베이스 매핑 정보에서 모든 엔터티를 가져오는 메서드. 이는 ORM에서 데이터베이스 테이블과 Java 클래스 간의 매핑 정보를 나타낸다.
  • persistent.getMappedClass(): 데이터베이스의 매핑된 엔터티에 해당하는 Java 클래스를 가져오는 메서드.
  • type.getDeclaredAnnotation(BsEntityListeners.class): Java 클래스에서 BsEntityListeners 어노테이션을 찾아 가져오는 메서드

이런 식으로 활용한 경우도 있다.

2) 필드 비교
해당 코드는 나도 리플랙션을 사용해보고 싶어서 코드를 짜본 것이다.
기존 데이터와 데이터를 비교해서 만약 업데이트 된 컬럼이 존재한다면 해당 컬럼을 가져와야하는 요구사항이 있었다.

각 테이블마다 히스토리 테이블이 있었고 테이블의 모든 컬럼을 가져오고 일일히 다 비교하는 코드를 매 히스토리 테이블마다 하는 중복되는 코드를 짜고 싶지 않아서 리플랙션을 사용해서 요구사항을 풀었다.

위의 두 예시를 통해 단순히 실무에서도 종종 아주 가끔 사용은 한다~ 정도로만 참고하면 될 것 같다.

📌 리플랙션의 단점

하지만 실무에서도 리플랙션 사용을 선호하지는 않는다. 크게 두가지 이유가 존재한다.

1) 성능 저하
리플렉션은 클래스의 바이트 코드를 이용하는 것이 아닌, 메모리에 해당 클래스의 특성을 투영한 데이터를 이용하므로 매 번 호출되는 메서드라도 최적화가 되지 않게 된다.
즉,런타임에 클래스의 구조를 조사하고 메서드를 찾아야 하기 때문에 반복적으로 호출되는 작업에 대해서는 성능이 저하될 수 있다.

2) Private 필드 접근 가능
접근 제어자와 상관없이 다 접근 가능하기 때문에 보안적인 문제가 발생한다.
invoke 메서드 호출 전에 setAccessible(true) 메서드를 호출해버리고 해당 값에 접근해버린다.

참고

profile
배우는 것이 즐겁다!
post-custom-banner

2개의 댓글

comment-user-thumbnail
2024년 4월 3일

ㅋㅋㅋㅋㅋㅋㅋㅋㅋ열콩모드

답글 달기
comment-user-thumbnail
2024년 4월 17일

리플렉션을 캐싱해버리는 방법도 있죵 ㅎㅎ 물론 가급적 안쓰는게 제일 좋긴 합니다요~

답글 달기