리플랙션
리플렉션이라는 말의 사전적의미는 투영 같은 느낌의 단어입니다.
이 리플렉션을 통해서 어떠한 요청이 온 파라미터값이나 클래스나 객체에있는 정보들을 쏙쏙 빼갈수 있습니다.
자바가 기본으로 제공하는 JDK동적 프록시 기술이나 CGLIB같은 프록시 생성 오픈소스 기술을활용하면
프록시 객체를 동적으로 만들어 낼 수 있다.
리플랙션 기술을 사용하면 클래스나 메서드의 메타정보를 동적으로 획등하고 코드도 동적으로 호출 할 수 있다.
정적인 코드를 리플랙션을 사용해서 Method라는 메타정보로 추상화한후 공통로직을 만들 수 있게 된다.
package hello.proxy.jdkdynamic;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@Slf4j
public class ReflectionTest {
@Test
void reflection0() throws NoSuchMethodException, ClassNotFoundException {
Hello target = new Hello();
//공통 로직 1 시작
log.info("start");
String result1 = target.callA();
log.info("result={}", result1);
//공통 로직 2 시작
String result2 = target.callB();
log.info("result={}", result2);
// 공통로직 1과 2는 내용 이 같지만 호출내용이 다르기때문에 메서드로 뽑아내거나 하기가 쉽지 않다
// 이럴땐 리플랙션을 사용하면 해결할 수 있다.
}
@Test
void reflection() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
//클래스 정보 가져오기
Class classHello = Class.forName("hello.proxy.jdkdynamic.ReflectionTest$Hello");
Hello target = new Hello();
// callA 메서드정보
Method methodCallA = classHello.getMethod("callA");
Object result1 =methodCallA.invoke(target);
log.info("result1={}",result1);
Method methodCallB = classHello.getMethod("callB");
Object result2 =methodCallA.invoke(target);
log.info("result2={}",result2);
}
@Test
void reflection2() throws Exception{
Class classHello = Class.forName("hello.proxy.jdkdynamic.ReflectionTest$Hello");
Hello target = new Hello();
// callA 메서드정보
Method methodCallA = classHello.getMethod("callA");
dynamicCall(methodCallA, target);
Method methodCallB = classHello.getMethod("callB");
dynamicCall(methodCallB, target);
}
private void dynamicCall(Method method,Object target)throws Exception{
log.info("start");
Object result1 =method.invoke(target);
log.info("result={}",result1);
}
@Slf4j
static class Hello{
public String callA(){
log.info("callA");
return "A";
}
public String callB(){
log.info("callB");
return "B";
}
}
}
주의
리플렉션을 사용하면 클래스와 메서드의 메타정보를 사용해서 애플리케이션을 동적으로 유연하게 만들수 있다 하지만
리플렉션 기술은 런타임에 동작하기 때문에 컴파일시에 오류를 잡을 수 없다.
리플랙션은 프레임워크 개발이나 또는 매우 일반적인 공통처리가 필요할때 부분적으로 주의해서 사용한다.
'Springboot' 카테고리의 다른 글
프록시 팩토리 (0) | 2023.08.14 |
---|---|
JDK동적프록시/CGLIB (0) | 2023.08.14 |
탬플릿 메서드 패턴 (0) | 2023.08.14 |
Springboot/ ThreadLocal (0) | 2023.08.14 |
Spring Data ElasticSearch NativeSearchQuery Paging 처리 (0) | 2022.12.07 |