You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
다음 포인트컷 지시자는 단독으로 사용하면 안된다. args, @args, @target
이번 예제를 보면 execution(* hello.aop..*(..)) 를 통해 적용 대상을 줄여준 것을 확인할 수 있다. args , @args , @target 은 실제 객체 인스턴스가 생성되고 실행될 때 어드바이스 적용 여부를 확인할 수 있다.
실행 시점에 일어나는 포인트컷 적용 여부도 결국 프록시가 있어야 실행 시점에 판단할 수 있다. 프록시가 없다면판단 자체가 불가능하다. 그런데 스프링 컨테이너가 프록시를 생성하는 시점은 스프링 컨테이너가 만들어지는 애플리케이션 로딩 시점에 적용할 수 있다. 따라서 args , @args , @target 같은 포인트컷 지시자가 있으면 스프링은 모든 스프링 빈에 AOP를 적용하려고 시도한다. 앞서 설명한 것 처럼 프록시가 없으면 실행 시점에 판단 자체가 불가능하다. 문제는 이렇게 모든 스프링 빈에 AOP 프록시를 적용하려고 하면 스프링이 내부에서 사용하는 빈 중에는 final로 지정된 빈들도 있기 때문에 오류가 발생할 수 있다.
따라서 이러한 표현식은 최대한 프록시 적용 대상을 축소하는 표현식과 함께 사용해야 한다.
[bean] voidhello.aop.order.OrderService.orderItem(String)
[orderService] 실행
[bean] Stringhello.aop.order.OrderRepository.save(String)
[orderRepository] 실행
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
-
6️⃣ args
✅ execution과 args의 차이점
7️⃣ @target, @Within
➡️ 정의
➡️ 설명
➡️@target vs @Within
@target은 인스턴스의 모든 메서드를 조인 포인트로 적용한다.@within은 해당 타입 내에 있는 메서드만 조인 포인트로 적용한다.쉽게 말해서 @target은 부모 클래스의 메서드까지 어드바이스를 다 적용하고, @Within은 자기 자신의 클래스에 정의된 메서드에만 어드바이스를 적용한다.
✅ AtTargetAtWithinTest
8️⃣ @annotation, @Args
✅ @annotation
정의
설명
다음과 같이 메서드(조인 포인트)에 애노테이션이 있으면 매칭한다.
✅ AtAnnotationTest
✅ args
정의
설명
9️⃣ bean
✅ BeanTest
🔟 매개변수 전달
다음은 포인트컷 표현식을 사용해서 어드바이스에 매개변수를 전달할 수 있다.
this, target, args,@target, @Within, @annotation, @Args
예시
포인트컷의 이름과 매개변수의 이름을 맞추어야 한다. 여기서는
arg로 맞추었다.
추가로 타입이 메서드에 지정한 타입으로 제한된다. 여기서는 메서드의 타입이
String다음과 같이 정의되는 것으로 이해하면 된다.
logArgs1:joinPoint.getArgs()[0]와 같이 매개변수를 전달 받는다.
logArgs2:args(arg,..)와 같이 매개변수를 전달 받는다.
logArgs3:@before를 사용한 축약 버전이다. 추가로 타입을String으로 제한했다.
this: 프록시 객체를 전달 받는다.
target: 실제 대상 객체를 전달 받는다.@target,@Within: 타입의 애노테이션을 전달 받는다.@annotation: 메서드의 애노테이션을 전달 받는다. 여기서는annotation.value()로 해당 애노테이션
실행 결과
Beta Was this translation helpful? Give feedback.
All reactions