리플렉션이란 클래스나 메소드의 메타 정보를 얻을 수 있는 것 이다.
@Test
void reflection1() throws Exception {
Class classHello = Class.forName("hello.proxy.jdkdynamic.ReflectionTest$Hello");
Hello target = new Hello();
Method methodCallA = classHello.getMethod("callA");
Object result1 = methodCallA.invoke(target);
log.info("result1={}", result1);
Method methodCallB = classHello.getMethod("callB");
Object result2 = methodCallB.invoke(target);
log.info("result2={}", result2);
}
저렇게.
Class.forName해서 클래스를 찾아온다.
$Hello는 ReflectionTest 클래스 안에 있는 내부 클래스라서 $가 붙은거다.
그리고 Method.
저렇게 이름으로 찾아온 클래스 안에 있는 메소드를 또 메소드 이름으로 메타정보를 가져올 수 있다.
invoke는 그 가져온 메타정보의 메소드를 실행하는 거다.
target 안에는 실제 인스턴스가 있어야 한다.
target 안에 있는 메소드 메타정보를 찾아 실행 하는 것 이다. 그래서 실제 인스턴스가 필요하다.
이렇게 메타 정보를 읽을 수 있으면,
private void dynamicCall(Method method, Object target) throws Exception {
log.info("start");
Object result = method.invoke(target);
log.info("result={}", result);
}
이런 식으로 동적으로 메타정보를 인자로 받아서 주는 인자에 따라 실행이 가능하다.
물론 target안에 메소드가 있어야 한다.
@Test
void reflection2() throws Exception {
Class classHello = Class.forName("hello.proxy.jdkdynamic.ReflectionTest$Hello");
Hello target = new Hello();
Method methodCallA = classHello.getMethod("callA");
dynamicCall(methodCallA, target);
Method methodCallB = classHello.getMethod("callB");
dynamicCall(methodCallB, target);
}
이런 식으로 쓴다.
클래스 정보로부터 메소드의 이름으로 메소드 메타 정보를 뽑고,
실제 그 클래스의 인스턴스를 만들고,
그 실제 인스턴스로 부터 메소드 메타정보로 메소드를 찾아 실행한다.
사실 리플렉션 안쓴다. 왠만해서는. (지금처럼 동적 프록시가 필요할 때 말고는)
런타임에 동적으로 클래스나 메소드의 메타 정보를 얻어오는 것 이다.
지금은 콜백도 있어서, 굳이 이럴 필요는 없는데,
JDK 동적 프록시 이해하려고 한거다.
'스프링 > 스프링 핵심 원리 - 고급편' 카테고리의 다른 글
36. JDK 동적 프록시 (0) | 2024.01.20 |
---|---|
34. 인터페이스 기반 프록시 vs 구체클래스 프록시 (0) | 2024.01.19 |
33. 구체클래스 프록시 적용 (0) | 2024.01.19 |
32. 구체 클래스에 프록시 적용 (0) | 2024.01.19 |
31. 로그트레이스 프록시 적용 (0) | 2024.01.19 |