프록시(AOP위주)

김종준·2023년 2월 3일
0

프록시... AOP를 위주로

AOP를 사용할 때 프록시를 활용하였는데 프록시는 무엇일까?

프록시의 핵심 목적은 메서드 호출을 인터셉트하고 필요한 경우 특정 메서드에 적용되는 어드바이스 체인을 실행하는 것이다.

어드바이스의 관리와 호출은 대부분 프록시와 독립적이며 스프링 AOP 프레임워크가 관리한다.

하지만 프록시는 모든 메서드를 호출하고 인터셉트하고 필요에 따라 어드바이스를 적용할 수 있도록 AOP 프레임워크에 전달할 책임이 있다.

JDK 동적 프록시

JDK 동적 프록시는 스프링에서 사용할 수 있는 가장 기본적인 프록시 타입이다.

클래스가 아닌 인터페이스 프록시만을 생성할 수 있다.

즉, 프록시를 적용하는 모든 객체는 적어도 하나의 인터페이스를 구현해야 하고, 프록시는 그 인터페이스를 구현한다.

JDK 프록시를 사용하면 JVM이 모든 메서드 호출을 인터셉트해 프록시의 invoke() 메서드로 라우트한다.

JDK 프록시는 invoke() 메서드에 들어가기 전까지는 어드바이스가 적용된 메서드와 어드바이스가 적용되지 않은 메서드 사이에서 아무런 결정을 하지 않는다.

이는 프록시의 어드바이스가 적용되지 않는 메서드에 대해서도 invoke() 메서드가 호출되고, 모든 검사가 이뤄진다.

심지어 리플렉션을 사용해 대상이 아닌 메서드도 호출한다는 의미이다.

이는 성능에 오버헤드를 발생시킨다.

CGLIB 프록시

CGLIB는 동적으로 새 클래스에 대한 바이트코드를 생성하고 이미 생성된 클래스를 사용할 수 있으면 재사용한다.

이때 생성되는 프록시 타입은 대상 객체 클래스의 하위 클래스가 된다.

CGLIB 프록시가 처음 생성되면 CGLIB는 각 메서드를 어떻게 처리할 것인지 스프링에게 물어본다.

CGLIB 프록시는 JDK 프록시와 달리 어드바이스가 적용되지 않는 메서드의 경우에는 직접 호출하여 적절한 바이트코드를 생성해 프록시로 인한 성능 오버헤드를 줄인다.

또 CGLIB 프록시는 메서드가 this를 반환할 수 있는지 판단한다.

this를 반환할 수 없을 때에는 메서드를 직접 호출할 수 있게 하여 런타임 성능 오버헤드를 줄인다.

0개의 댓글