728x90
자바 리플렉션의 기초
리플렉션의 정의
- 자바 리플렉션은 컴파일 시점에 알 수 없는 클래스나 메서드, 필드 등에 대한 정보를 얻거나, 그 정보를 사용하여 객체를 생성하거나, 메서드를 호출하거나, 필드에 값을 설정하거나 하는 등의 작업을 할 수 있는 기능이다.
- 마치 거울을 통해 자신의 모습을 비추어 보는 것처럼, 객체의 내부 구조를 살펴볼 수 있다는 의미에서 "리플렉션(reflection)"이라는 이름이 붙여졌다.
- 리플렉션을 사용하면 다음과 같은 작업을 수행할 수 있다.
- 클래스 이름, 상위 클래스, 인터페이스, 생성자, 메소드, 필드 등의 정보를 얻을 수 있다.
- 객체를 생성하거나, 변수의 값을 변경하거나, 메소드를 호출할 수 있다.
리플렉션의 사용 예:
- 리플렉션은 다양한 용도로 사용될 수 있다. 다음은 몇 가지 예시다.
- 프레임워크에서
- 프레임워크는 다양한 클래스를 사용하는 경우가 많다. 리플렉션을 사용하면 프레임워크가 런타임에 필요한 클래스를 동적으로 찾을 수 있다. 예를 들어, 스프링 프레임워크는 리플렉션을 사용하여 어노테이션을 처리한다.
- IDE에서
- IDE는 개발자가 코드를 작성하는 데 도움을 주는 다양한 기능을 제공한다. 리플렉션을 사용하면 IDE가 코드의 구조를 이해하고 자동 완성, 오류 검사 등의 기능을 제공할 수 있다.
- 테스트에서
- 테스트에서는 객체의 내부 상태를 검사하거나, 다양한 메소드를 호출하는 등의 작업이 필요하다. 리플렉션을 사용하면 테스트 코드를 보다 유연하고 간결하게 작성할 수 있다.
- 프레임워크에서
아래는 기본 사용 예시 코드다.
// User 클래스 정의
public class User {
private String name;
public User(String name) {
this.name = name;
}
public String getName() {
return name;
}
// ... 기타 필드 및 메소드 ...
}
// 리플렉션을 사용해 User 클래스의 메타데이터를 분석하고 메소드를 호출하는 예시
public class ReflectionExample {
public static void main(String[] args) throws Exception {
// User 클래스의 Class 객체를 가져온다.
Class<?> clazz = Class.forName("User");
// User 클래스의 생성자를 통해 객체를 생성한다.
User user = (User) clazz.getDeclaredConstructor(String.class).newInstance("Alice");
// getName 메소드 정보를 가져온다.
Method method = clazz.getMethod("getName");
// getName 메소드를 호출한다.
String name = (String) method.invoke(user);
System.out.println("User's name: " + name); // 출력: User's name: Alice
}
}
JPA에서 리플렉션을 사용하는 이유
- JPA에서 리플렉션을 사용하는 이유는 프록시 객체를 생성하기 위함이다.
- 프록시 객체는 데이터베이스에서 로드하지 않고, 필요한 시점에 로드하여 실제 엔티티 객체와 동일한 인터페이스를 제공하는 객체이다.
- JPA는 리플렉션을 사용하여 엔티티 객체에 대한 정보를 얻는다.
- 리플렉션을 사용하면 컴파일 시점에 알 수 없는 클래스나 메서드, 필드 등에 대한 정보를 얻을 수 있기 때문에, 엔티티 객체에 대한 정보를 얻어서 프록시 객체를 생성할 수 있다.
- 리플렉션을 통해 객체를 생성하는 과정은 다음과 같다:
- 먼저 객체의 타입 정보를 얻는다.
- 해당 타입의 생성자 정보를 얻는다.
- 생성자 정보를 사용하여 객체를 생성한다.
- 이때 엔티티 객체에 기본 생성자가 없으면 생성자를 호출할 수 없기 때문에 객체를 생성할 수 없다.
- 따라서 모든 엔티티에 기본 생성자를 선언하여 JPA가 프록시 객체를 생성할 수 있도록 해야 한다.
이전 포스팅(ResponseDto에 기본 생성자 있어야 하는 이유)에서 프록시와 리플렉션이라는 개념이 첫문단에 나온다. 일단 설명을 적긴 적었는데, 누가 프록시가 뭐야? 리플렉션 매커니즘이 뭔데? 라고 물어보면 잘 대답을 못할 것 같았다. 그래서 해당 개념을 공부하면서 확실히 기술 블로그를 운영하면서 기술에 대한 이해도가 높아진것같다.그리고 공부한 내용을 정리하는 것 또한 중요하다는 생각이 들었다.
'프로그래밍 언어 > JAVA' 카테고리의 다른 글
AtomicInteger를 활용한 파일 저장 순서 동기화 문제 해결 (0) | 2024.02.04 |
---|---|
[JAVA] 코드 최적화를 위한 매직 상수 사용법 (4) | 2023.12.31 |
[JAVA] 자바 인터페이스에서 public과 private 접근 제한자 활용하기 (3) | 2023.12.24 |
[JAVA] 람다 표현식에서 final 변수나 effectively final 변수를 사용해야 하는 이유 (0) | 2023.12.01 |
[JAVA] Java와 Spring, JPA에서의 프록시 객체 이해하기 (1) | 2023.11.08 |