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
new DefaultPointCutAdvisor : Advisor 인터페이스의 가장 일반적인 구현체이다. 생성자를 통해 하나의 포인트컷과 하나의 어드바이스를 넣어주면 된다. 어드바이저는 하나의 포인트 컷과 하나의 어드바이스로 구성된다.
Pointcut.TRUE : 항상 true를 반환하는 포인트컷이다. 이후에 직접 포인트컷을 구현해볼 것이다.
new TimeAdvice() : 앞서 개발한 TimeAdvice 어드바이스를 제공한다.
proxyFactory.addAdvisor(advisor) : 프록시 팩토리에 적용할 어드바이저를 지정한다. 어드바이저는 내부에 포인트 컷과 어드바이스를 모두 가지고 있다. 따라서 어디에 어떤 부가 기능을 적용해야 할지 어드바이스 하나로 알 수 있다. 프록시 팩토리를 사용할 때 어드바이저는 필수이다.
그런데 생각해보면 이전에 분명히 proxyFactory.addAdvice(new TimeAdvice()) 이렇게 어드바이저가 아니라 어드바이스를 바로 적용했다. 이것은 단순히 편의 메서드이고 결과적으로 해당 메서드 내부에서 지금 코드와 똑같은 다음 어드바이저가 생성된다.
DefaultPointcutAdvisor(Pointcut.TRUE, new TimeAdvice())
실행결과
실행 결과를 보면 save(), find() 각각 모두 어드바이스가 적용된 것을 확인할 수 있다.
예제 코드2 - 직접 만든 포인트컷
이번에는 save() 메서드에는 어드바이스 로직을 적용하지만, find() 메서드에는 어드바이스 로직을 적용하지 않도록 해보자.
물론 과거에 했던 코드와 유사하게 어드바이스에 로직을 추가해서 메서드 이름을 보고 코드를 실행할지 말지 분기를 타도 된다. 하지만 이런 기능에 특화되어서 제공되는 것이 바로 포인트컷이다.
AOP 적용 수 만큼 프록시가 생성된다고 착각하는 경우가 많은데, 스프링은 AOP를 적용할 때 최적화를 진행해서 지금처럼 프록시는 하나만 만들고 하나의 프록시에 여러 어드바이저를 적용한다.
정리하면, 하나의 target에 여러 AOP가 동시에 적용되어도 스프링의 AOP는 target마다 하나의 프록시만 생성한다.
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.
Uh oh!
There was an error while loading. Please reload this page.
포인트컷, 어드바이스 , 어드바이저 - 소개
포인트 컷 (PointCut)
어드바이스(Advice)
어드바이저(Advisor)
부가기능 로직을 적용해야 하는데, 포인트 컷으로 어디에> 어드바이스로 어떤 로직을 > 어디에 어떤 로직을 적용할지 다 알고 있는 것이 어드바이저 이다.
쉽게 기억하기
역할과 책임
참고
예제코드 1 - 어드바이저
어드바이저는 하나의 포인트 컷과 하나의 어드바이스를 가지고 있다.
프록시 팩토리를 통해 프록시를 생성할때 어드바이저를 제공하면 어디에 어떤 기능을 제공할지 알 수 있다.
new DefaultPointCutAdvisor:Advisor인터페이스의 가장 일반적인 구현체이다. 생성자를 통해 하나의 포인트컷과 하나의 어드바이스를 넣어주면 된다. 어드바이저는 하나의 포인트 컷과 하나의 어드바이스로 구성된다.Pointcut.TRUE: 항상true를 반환하는 포인트컷이다. 이후에 직접 포인트컷을 구현해볼 것이다.new TimeAdvice(): 앞서 개발한TimeAdvice어드바이스를 제공한다.proxyFactory.addAdvisor(advisor): 프록시 팩토리에 적용할 어드바이저를 지정한다. 어드바이저는 내부에 포인트 컷과 어드바이스를 모두 가지고 있다. 따라서 어디에 어떤 부가 기능을 적용해야 할지 어드바이스 하나로 알 수 있다. 프록시 팩토리를 사용할 때 어드바이저는 필수이다.proxyFactory.addAdvice(new TimeAdvice())이렇게 어드바이저가 아니라 어드바이스를 바로 적용했다. 이것은 단순히 편의 메서드이고 결과적으로 해당 메서드 내부에서 지금 코드와 똑같은 다음 어드바이저가 생성된다.DefaultPointcutAdvisor(Pointcut.TRUE, new TimeAdvice())실행결과
예제 코드2 - 직접 만든 포인트컷
이번에는 save() 메서드에는 어드바이스 로직을 적용하지만, find() 메서드에는 어드바이스 로직을 적용하지 않도록 해보자.
물론 과거에 했던 코드와 유사하게 어드바이스에 로직을 추가해서 메서드 이름을 보고 코드를 실행할지 말지 분기를 타도 된다. 하지만 이런 기능에 특화되어서 제공되는 것이 바로 포인트컷이다.
이번에는 해당 요구사항을 만족하도록 포인트컷을 직접 구현해보자.
pointcut 관련 인터페이스 - 스프링 제공
직접 구현한 포인트 컷
MyPointcut
Pointcut인터페이스를 구현한다.true를 반환하도록 했고 메서드 비교기능은MyMethodMatcher를 사용한다.MyMethodMatcher
isRuntime(),matches(...args): isRuntime()이 값이 참이면matches(..args)메서드가 대신 호출된다. 동적으로 넘어오는 매개변수를 판단 로직으로 사용할 수 잇다.isRuntime()이 false인 경우 클래스의 정적 정보만 사용하기 대문에 스프링이 내부에서 캐싱을 통해 성능 향상이 가능하지만,isRuntime()이 true 인 경우 매개변수가 동적으로 변경된다고 가정하기 때문에 캐싱을 하지 않는다.new DefaultPointcutAdvisor(new MyPoincut(), new TimeAdvice())실행결과
그림으로 정리
save() 호출 : 포인트컷이 적용되어야 하는 경우

find() 호출 : 포인트컷이 적용되지 않는 경우
예제 코드 3 - 스프링이 제공하는 포인트컷
스프링은 우리가 필요한 포인트컷을 이미 대부분 제공한다.
이번에는 스프링이 제공하는
NameMatchMethodPointcut를 사용해서 구현해보자.AdvisorTest - advisorTest3() 추가
스프링이 제공하는 포인트컷
스프링은 무수히 많은 포인트컷을 제공한다.
대표적인 것 몇가지
PatternMatchUtils를 사용한다.*xxx*허용JdkRegexpMethodPointcut: JDL 정규포현식을 기반으로 포인트 컷을 매칭한다.TruePointcut: 항상 창을 변환한다.AnnotationMathingPointcut: 애노테이션으로 매칭한다.AspectJExpressionPointcut: aspectJ 표현식으로 매칭한다.가장 중요한 것은 aspectJ 표현식
여기에서 사실 다른것은 중요치 않고 실무에서는 사용도 편리하고 기능도 많은 aspectJ 표현식을 기반으로 사용하는
AspectJExpressionPointcut을 사용하게 된다.aspectJ표현식과 사용방법은 중요해서 AOP 설명때 자세히
예제 코드 4 - 여러 어드바이저 함께 적용
어드바이저는 하나의 포인트컷과 하나의 어드바이스를 가지고 있다.
advisor1,advisor2모두 항상 true를 반환하도록 설정했다. 따라서 둘다 어드바이스가 적용된다.여러 프록시의 문제
이 방법이 잘못된 것은 아니지만, 프록시를 2번 생성해야 한다는 문제가 있다. 만약 저용해야 하는 어드바이저가 10개라면 10개의 프록시를 생성해야 한다.
하나의 프록시, 여러 어드바이저
스프링은 이 문제를 해결하기 위해 하나의 프록시에 여러 어드바이저를 적용할 수 있게 만들어두었다.

addAdvisor()를 통해서 어드바이저를 등록하면 된다.advisor가 호출된다. 여기서는 2,1 순서로 등록했다.정리
결과적으로 여러 프록시를 사용할 때와 비교해서 결과는 같고 성능은 더 좋다.
중요
All reactions