리플렉션
- 프록시를 사용해서 기존 코드를 변경하지 않고, 로그 추적기란 부가 기능을 적용하였는데, 대상 클래스 수 만큼 로그 추적을 위한 프록시 클래스를 만드는 번거로움이 있었다. 프록시 클래스들의 모양이 거의 동일하므로 이를 해결하기 위한 방법
위와 같은 경우 callA와 callB를 제외하곤 나머지 부분이 공통이다. 이 부분들을 따로 만들지 않고 동적으로 관리하는 것이 리플렉션이다.
문제점 : 가급적이면 사용하면 안된다. 클래스의 메타정보를 사용해서 동적으로 유연하게 만들지만, 런타임에 동작하기 때문에 컴파일 시점에 오류를 잡을 수 없다. 따라서, 리플렉션은 일반적으로 사용하면 안되고 매우 일반적인 공통 처리가 필요할 떄 부분적으로 주의해서 사용해야 한다.
JDK 동적 프록시
- 동적 프록시 기술을 사용하면 개발자가 직접 프록시 클래스를 만들지 않아도 된다.
제공되는 파라미터로는 Object proxy(프록시 자신), Method method(호출한 메서드), Object[] args(메서드를 호출할 때 전달한 인수)가 있다.
이제 기존에 사용했던 프록시 방식과 달리 프록시 클래스를 따로 생성할 필요가 없다. 그렇기 때문에 같은 기능으로 동작하는 클래스를 1:1로 모두 만들필요 없이 하나와 형변환을 이용해서 이용할 수 있다. JDK 동적 프록시를 사용함으로 써 InvocationHandler를 이용하여 Proxy 객체를 생성하여 ProxyClass를 대체하는 것이다.
하지만 모든 메서드에 적용이 되다보니, 로그를 남기지 않아야하는 메서드도 호출되게 된다.
그래서 PatternMatchUtils를 이용해서 특정 패턴의 경우 적용되지 않도록 한다.
또한, 이 경우에는 클래스가 인터페이스를 필요로 하는데, 인터페이스 없이 사용하려면 CGLIB를 사용하여야 한다.
CGLIB
- Code Generator Library의 준말로, 바이트코드를 조작해서 동적으로 클래스를 생성하는 기술을 제공하는 라이브러리이다. 인터페이스가 없어도 구체 클래스만 가지고 동적 프록시를 만들어 낼 수 있고, 외부 라이브러리이지만 스프링 프레임워크 내부에 포함되어있다. CGLIB를 직접 사용하는 경우는 거의 없지만 ProxyFactory에서 기술 사용에 도움이 된다.
CGLIB는 MethodInterceptor를 제공한다.
제약
- 부모 클래스의 생성자를 체크해야 한다. 자식 클래스 동적 생성으로 인한 기본 생성자 필요
- 클래스에 fianl 키워드가 붙으면 상속이 불가능하다 -> CGLIB에서 예외 발생
- 메서드에 final 키워드가 붙으면 해당 메서드를 오버라이딩 할 수 없다. -> CGLIB에서는 프록시 로직이 동작하지 않음
인터페이스가 있는 경우랑 없는 경우를 구분해서 만들기 까다로우니, 두 기술을 함께 사용할 수 있는 ProxyFactory에 대해 다음에 정리해볼 예정이다.
'일간 회고록(TIL)' 카테고리의 다른 글
[22.10.03] Daily 회고록 (백엔드 면접, 과제형 테스트 준비) (1) | 2022.10.04 |
---|---|
[22.10.01] Daily 회고록 (이펙티브 자바 - 정적팩토리, 열거, 플라이웨이트) (0) | 2022.10.02 |
[22.09.19] Daily 회고록 (stomp failover 문제 해결) (0) | 2022.09.20 |
[22.09.18] Daily 회고록 (프록시, 프록시 패턴, 데코레이터 패턴) (0) | 2022.09.19 |
[22.09.14] Daily 회고록 (CloudWatch를 활용한 프로젝트 로그 저장, 영어 스피치) (0) | 2022.09.15 |