[Spring Boot] 2. Reflection_1.Ex01

김미숙's avatar
Mar 20, 2025
[Spring Boot] 2. Reflection_1.Ex01

Reflection

‼️

📌 개념

👉 Java에서 Class, Interface, Fild, Method 등에 대한 정보를 Runtime에 동적으로 접근하고 조작할 수 있는 강력한 기능
  • Reflection을 사용하면 프로그램이 자신의 구조에 대한 정보를 직접 조사하고, 실행 중에 객체의 Class를 알아내거나, Method와 Fild에 접근하고 Method를 호출하는 것이 가능하다 👉 이를 “각 Class의 Meta Data를 읽어온다” 라고 표현한다.
  • 여기서 Meta Data를 가져온다는 것은 Class에 구현된 모든 Code, 또는 Method 내부에 구현된 모든 Code를 확인하는 것이 아니라, 특정 정보인 Meta Data를 조회할 수 있다는 의미
  • Java의 Reflection API를 사용하여 Class 객체에서 다음과 같은 정보 (Meta Data)를 가져올 수 있다.
    • Class 이름
    • Method 정보
    • Fild 정보
    • 생성자 정보
    • 상위 Class 및 Interface 정보
    • Annotation 정보

리플렉션의 단점

  1. 성능 저하 🚨
      • 일반적인 코드보다 느림 (메서드 호출 시 invoke() 사용).
  1. 보안 문제 🔒
      • setAccessible(true)private 필드/메서드에 접근 가능 → 보안 취약점이 생길 수 있음.
  1. 컴파일 타임 오류 발견 불가
      • 일반적인 코드에서는 컴파일러가 오류를 잡아주지만, Reflection을 사용하면 런타임 오류 발생 가능.
 

정리

Reflection은 런타임에 클래스, 메서드, 필드 등의 정보를 조회하고 조작하는 기능
getMethods(), getFields(), getConstructors() 등을 사용해 클래스 구조 탐색
setAccessible(true)를 사용하면 private 필드/메서드에도 접근 가능
invoke()로 동적으로 메서드 실행 가능
Spring, JSON 변환, AOP(Aspect-Oriented Programming) 등에 활용됨
✅ 대량의 Data를 작업할 시 Computer Resource를 많이 사용하게 되고, 속도 역시 느려질 수 밖에 없다
⚠️ 성능 저하와 보안 문제 때문에 남용하면 안 됨!

Situation

  • A회사는 routing Program을 만들어서 B회사에 판매
  • B회사는 동적 바인딩으로 method 구현
  • But, B회사에 기능이 추가될 때마다 A회사에게 기능을 추가해 달라고 요청해야 하고 A회사는 B회사의 요청대로 Code를 수정해야 하는 번거로움 발생
 
package ex01; import java.util.Scanner; interface Controller { void login(); void join(); void logout(); } // 1. A회사 class Dispatcher { Controller controller; public Dispatcher(Controller controller) { this.controller = controller; } public void routing(String path) { if (path.equals("/login")) { controller.login(); } else if (path.equals("/join")) { controller.join(); } else if (path.equals("/logout")) { controller.logout(); } } } // 2. B회사 -> 구매할게 Controller 구현해서 만들어 class UserController implements Controller { @Override public void login() { System.out.println("Login call"); } @Override public void join() { System.out.println("Join call"); } @Override public void logout() { System.out.println("Logout call"); } } public class App { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String path = sc.nextLine(); UserController uc = new UserController(); Dispatcher ds = new Dispatcher(uc); ds.routing(path); } }
출력 결과
C:\workspace\tools\jdk-21\bin\java.exe "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2024.3.2.1\lib\idea_rt.jar=52444:C:\Program Files\JetBrains\IntelliJ IDEA 2024.3.2.1\bin" -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 -classpath C:\workspace\spring_lec\ref\out\production\ref ex01.App /login Login call Process finished with exit code 0
C:\workspace\tools\jdk-21\bin\java.exe "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2024.3.2.1\lib\idea_rt.jar=52437:C:\Program Files\JetBrains\IntelliJ IDEA 2024.3.2.1\bin" -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 -classpath C:\workspace\spring_lec\ref\out\production\ref ex01.App /join Join call Process finished with exit code 0
C:\workspace\tools\jdk-21\bin\java.exe "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2024.3.2.1\lib\idea_rt.jar=52297:C:\Program Files\JetBrains\IntelliJ IDEA 2024.3.2.1\bin" -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 -classpath C:\workspace\spring_lec\ref\out\production\ref ex01.App /logout Logout call Process finished with exit code 0
 
Share article

parangdajavous