리플렉션(Reflection)이란,
컴파일이 아닌 런타임 시점에 Meta Data(클래스, 메서드, 필드 등의 정보)를 동적으로 분석하고 조작할 수 있는 기능이다
리플렉션의 기능
클래스 정보 조회
위의 예시 코드와 같이 클래스 이름, 패키지명, 부모 클래스, 구현 인터페이스 등을 가져올 수 있다
생성자 정보 조회 및 동적 객체 생성
특정 클래스의 생성자를 이용해 객체를 동적으로 생성할 수 있다(newInstance())
필드 정보 조회 및 값 변경
클래스의 멤버 변수(필드)를 읽거나 수정할 수 있다
메서드 정보 조회 및 실행
클래스의 메서드 정보를 얻고 실행할 수 있다
private 접근 기능
private 접근 제어자를 무시하고 필드나 메서드에 접근 가능하다
java.lang.reflect 패키지를 사용해 리플렉션을 사용할 수 있다
아래는 클래스 정보를 얻는 3가지의 방법이다
package com.example.reflection.ReflectionExample
public Class ReflectionExample {
public static void main(String[] args) throws Exceptions {
//1번 방법
Class clazz = ClassName.class;
//2번 방법
Class clazz = Class.forName("com.example.reflection.className");
//3번 방법
ClassName clazz = className.getClass();
}
}
멤버 정보를 얻고 생성자로 새로운 객체를 생성하는 방법이다
private 접근제한자를 무시하고, 메소드를 호출할 수도 있다
com.example.reflection.ReflectionExample
import java.lang.reflext.*;
public class ReflectionExample {
public static void main(Stirng[] args) throws exception {
//클래스 정보 얻기
Class<?> clazz = ClassName.class;
//생성자 정보 얻기
Constructor<?>[] constructors = clazz.getDeclaredConstructors();
for (Constructor constructor : constructors) {
//생성자 이름 얻기
String constructorName = constructor.getName();
//매개변수 정보 얻기
Class[] parameters = constructor.getParameterTypes();
}
//생성자로 객체 생성
Constructor<?> constructor = clazz.getConstructor(String.class);
Object object = constructor.newInstatnce("parameter");
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
//메소드 이름 얻기
String methodName = method.getName();
//매개변수 정보 얻기
Class[] parameters = method.getParameterTypes();
}
// private 메서드 가져오기
Method method = clazz.getDeclaredMethod("methodName", int.class, int.class);
method.setAccessible(true); // private 접근 허용
// 메서드 실행
Object result = method.invoke(className, 5, 10);
}
}
Class 객체는 클래스 파일의 경로 정보를 가지고 있기 때문에 상대 경로의 다른 리소스(이미지, 텍스트, property)파일의 정보를 얻을 수 있다
com.example.reflection.ReflectionExample
import java.lang.reflext.*;
public class ReflectionExample {
public static void main(Stirng[] args) {
//클래스 정보 얻기
Class clazz = ClassName.class;
//클래스 경로로부터의 리소스 파일의 정보 얻기
String photopath = clazz.getResource("images/photo").getPath();
}
}
JPA를 사용해 JpaRepository를 구현하면 xxRepository.findById 메서드등을 통해 객체를 조회할 수 있는데,
이러한 객체를 반환해주는 로직에서 reflection이 적용된 것이다.
JPA 대표적인 적용 예시
1) JPA에서 객체 조회시 데이터
2) @RequestBody 사용 시 DTO 객체에 데이터 정보 set
3) 테스트 케이스 작성시 private 메서드를 테스트할 때
이외에도 메타데이터를 조회할 떄 리플렉션이 사용된다
아래는 자바 공식문서의 리플렉션 설명이다
https://docs.oracle.com/javase/tutorial/reflect/class/index.html
Lesson: Classes (The Java™ Tutorials > The Reflection API)
The Java Tutorials have been written for JDK 8. Examples and practices described in this page don't take advantage of improvements introduced in later releases and might use technology no longer available. See Dev.java for updated tutorials taking advantag
docs.oracle.com
리플렉션의 쓰임
리플렉션은 보통 JVM(Java Virtual Machine)에서 실행되는 어플리케이션의 실행 시점의 행동을 설정하거나 수정하는 능력을 요구하는 프로그램 들에서 사용된다
이것은 상당히 발전된 특징이며 언어에 대한 강한 기초 기반을 가진 개발자들에 의해서만 사용되어야한다
이 경고를 가지고 리플렉션을 바라본다면, 리플렉션은 강한 기술이며 불가능할 수도 있는 운영을 수행하는 어플리케이션을 가능하게 한다
확장성 기능
한 어플리케이션은 그 자격을 충분히 갖춘 이름을 사용하는 확장성 객체의 인스턴스를 생성하며 외부의 사용자 정의 클래스들을 만들 수 있다
클래스 브라우저들과 시각적 개발 환경
한 클래스 브라우저는 클래스들의 멤버를 열거할 수 있어야 한다
시각적 개발 환경들은 정확한 코드를 씀으로써 개발자를 돕기 위해 리플렉션으로 타입 정보를 사용하는 것에서 이로울 수 있다
디버거들과 테스트 도구
디버거들은 프라이빗 접근 제한의 클래스 멤버를 검사할 수 있어야 한다
테스트 하네스들은 클래스에서 정의된 발견 가능한 API 들을 시스템적으로 호출하는 데, 테스트 단위에서 높은 수준의 코드 보완하는 것에 리플렉션을 사용할 수 있다
리플렉션의 단점
리플렉션은 강하지만 무차별적으로 사용되어선 안된다
리플렉션 없이 기능을 수행하는 것은 가능하며, 그렇게 하면 사용하는 것을 꺼리는 것을 선호하게 된다
리플렉션을 통해 코드에 접근할 떄 다음의 염려를 가져야 한다
수행 오버헤드
리플렉션이 동적으로 해결되는 타입들을 포함하기 떄문에, 특정 JVM 최적화가 수행되지 않을 수 있다
연관되어, 리플렉션을 포함한 기능들은 그들의 리플렉션을 포함하지 않은 반대 부분보다 수행이 느릴 수 있고, 수행에 민감한 어플리케이션에서 빈번하게 호출되는 코드의 부분에서는 피해야한다
보안 정책
리플렉션은 보안 매니져 아래에서 실행될 때 실재하지 않을 수 있는 런타임 허가를 요구한다
이는 Applet에 있는 것 같은 경직된 보안 컨텍스트에서 실행되어야하는 코드에서는 중요한 고려이다
내부의 노출
리플렉션이 리플렉션이 없는 코드에서 금지될 수 있는 기능, 예를 들면 private 접근 제한의 필드나 메소드들을 수행하는 코드를 허용하기 때문에 리플렉션을 사용하는 것은 예상되지 않는, 코드에 장애를 일으키거나 이식성을 파괴할 수 있는 부가적인 효과를 낳을 수 있다
리플렉션을 사용하는 코드는 추상성을 파괴하며 그에 따라 플랫폼의 업그레이드에 따라 행동을 바꿀 수 있다
오늘도 하나 알아가서 좋다
내일도 열심히 하자 ~
'[Kotlin&Spring] 5기 내일배움캠프' 카테고리의 다른 글
| [Kotlin&Spring] 5기 일정 관리 앱 만들기 트러블슈팅 -JPQL (0) | 2025.02.12 |
|---|---|
| [Kotlin&Spring] 5기 컴파일 방식들과 자바의 컴파일 (1) | 2025.02.11 |
| [Kotlin&Spring] 5기 운영체제의 개념을 알아보자 (1) | 2025.02.07 |
| [Kotlin&Spring] 5기 싱글톤 패턴과 Spring Framework에서 단점 해결 방안 (1) | 2025.02.06 |
| [Kotlin&Spring] 5기 ORM과 영속성 컨텍스트 - JPA (0) | 2025.02.05 |