지금까지 프록시를 사용해서 기조 코드를 변경하지 않고도 로그 추적기라는 부가 기능을 제공할 수 있었다.
문제는 대상 클래스만큼 로그 추적을 위한 프록시 클래스를 만들어줘야 한다는 점임.
자바는 기본으로 JDK 동적 프록시 기술을 제공하고, CGLIB같은 프록시 생성 오픈 소스 기술도 있음. 이를 이용하면 프록시 하나만 만들고도 이전과 같이 프록시를 적용할 수 있다.
JDK의 동적 프록시 기술을 이해하려면 자바의 리플렉션 기술을 기본적으로 이해해야 한다.
코드를 통해 다음과 같은 상황을 가정해보자.
@Slf4j
public class ReflectionTest {
@Test
void reflection0() {
Hello target = new Hello();
//공통 로직 1 시작
log.info("start");
String result1 = target.callA();
log.info("result1 = {}", result1);
// 공통 로직 1 종료
// 공통 로직 2 시작
log.info("start");
String result2 = target.callB();
log.info("result2 = {}", result2);
// 공통 로직 2 종료
}
@Slf4j
static class Hello {
public String callA() {
log.info("callA");
return "A";
}
public String callB() {
log.info("callB");
return "B";
}
}
}
위의 코드에서 공통 로직 1과 공통 로직 2는 호출하는 메서드만 다르고 전체 코드 흐름은 완전히 같다.
그럼 공통 로직1과 공통로직 2를 하나의 메서드로 추출할 수 있지 않을까?
그러고 싶지만 사실 중간에 호출하는 메서드가 다르기 때문에 생각보단 간단하지 않다.
이를 해결하려면 공통 로직을 호출하는 코드인 target.callA()
, target.callB()
이 부분을 동적으로 처리해야 하기 때문. 파라미터나 변수도 아니고 코드 자체를 어떻게 동적으로 처리할까?
이때 사용하는게 리플렉션임