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
Q. 예를 들어서 어떤 스프링 빈이 advisor1 , advisor2 가 제공하는 포인트컷의 조건을 모두 만족하면 프록시 자동 생성기는 프록시를 몇 개 생성할까?
A. 프록시 자동 생성기는 프록시를 하나만 생성한다. 왜냐하면 프록시 팩토리가 생성하는 프록시는 내부에 여러 advisor 들을 포함할 수 있기 때문이다. 따라서 프록시를 여러 개 생성해서 비용을 낭비할 이유가 없다.
프록시 자동 생성기 상황별 정리
advisor1 의 포인트컷만 만족 프록시1개 생성, 프록시에 advisor1 만 포함
advisor1 , advisor2 의 포인트컷을 모두 만족 프록시1개 생성, 프록시에 advisor1 , advisor2 모두 포함
advisor1 , advisor2 의 포인트컷을 모두 만족하지 않음 프록시가 생성되지 않음
이후에 설명할 스프링 AOP도 동일한 방식으로 동작
정리
자동 프록시 생성기인 AnnotationAwareAspectJAutoProxyCreator 덕분에 편리하게 프록시 적용 가능
이제 Advisor만 스프링 빈으로 등록하면 됨
Advisor = Pointcut + Advice
Aspect AOP
스프링 애플리케이션에 프록시를 적용하려면 포인트컷과 어드바이스로 구성되어 있는 어드바이저( Advisor )를 만들어서 스프링 빈으로 등록하면 된다.
그러면 나머지는 앞서 배운 자동 프록시 생성기가 모두 자동으로 처리해준다. 자동 프록시 생성기는 스프링 빈으로 등록된 어드바이저들을 찾고, 스프링 빈들에 자동으로 프록시를 적용해준다.
물론 포인트컷이 매칭되는 경우에 프록시를 생성한다.
스프링은 @Aspect 애노테이션으로 매우 편리하게 포인트컷과 어드바이스로 구성되어 있는 어드바이저 생성 기능을 지원한다.
참고
@Aspect는 관점 지향 프로그래밍(AOP)을 가능하게 하는 AspectJ 프로젝트에서 제공하는 애노테이션
이다. 스프링은 이것을 차용해서 프록시를 통한 AOP를 가능하게 한다. 우선 이 애노테이션을 사용해서 스프링이 편리하게 프록시를 만들어준다고 생각하면 된다.
LogTraceAspect
packagehello.proxy.config.v6_aop.aspect;
importhello.proxy.trace.TraceStatus;
importhello.proxy.trace.logtrace.LogTrace;
importlombok.extern.slf4j.Slf4j;
importorg.aspectj.lang.ProceedingJoinPoint;
importorg.aspectj.lang.annotation.Around;
importorg.aspectj.lang.annotation.Aspect;
@Slf4j@AspectpublicclassLogTraceAspect {
privatefinalLogTracelogTrace;
publicLogTraceAspect(LogTracelogTrace){
this.logTrace = logTrace;
}
//패키지 경로 및 하위의 모든 클래스, 메서드 Aop 적용 하겠다는 뜻@Around("execution(* hello.proxy.app..*(..))")
//ProceedingJoinPoint : 대상 메서드를 실행할 수 있게 해주는 객체publicObjectexecute(ProceedingJoinPointjoinPoint) throwsThrowable {
TraceStatusstatus = null;
try {
Stringmessage = joinPoint.getSignature().toShortString();
status = logTrace.begin(message);
//로직 호출Objectresult = joinPoint.proceed();
logTrace.end(status);
returnresult;
} catch (Exceptione) {
logTrace.exception(status, e);
throwe;
}
}
}
@Aspect : 애노테이션 기반 프록시를 적용할 때 필요
@Around("execution(* hello.proxy.app..*(..))")
@Around의 값에 포인트컷 표현식을 넣음, 표현식은 AspectJ 표현식을 사용
@Around의 메서드는 어드바이스 (Advice)가 됨
ProceedingJoinPoint joinPoint: 어드바이스에서 살펴본 MethodInvocation invocation 과 유사한 기능, 내부에 실제 호출 대상, 전달 인자, 그리고 어떤 객체와 어떤 메서드가 호출되었는지 정보 포함 되어 있음
JoinPoint.proceed() : 실제 호출 대상 (target)을 호출
AopConfig
packagehello.proxy.config.v6_aop;
importhello.proxy.config.AppV1Config;
importhello.proxy.config.AppV2Config;
importhello.proxy.config.v6_aop.aspect.LogTraceAspect;
importhello.proxy.trace.logtrace.LogTrace;
importorg.springframework.context.annotation.Bean;
importorg.springframework.context.annotation.Configuration;
importorg.springframework.context.annotation.Import;
/** * Spring Aop 설정을 구성하는 클래스 * LogTraceAspect를 Spring Bean으로 등록해서 * Aop 기능을 실제로 동작하게 함 * */@Configuration//스프링 설정 클래스 애노테이션, 내부에 정의된 @Bean 메서드는 모두 스프링 빈으로 등록@Import({AppV1Config.class, AppV2Config.class})
publicclassAopConfig {
@BeanpublicLogTraceAspectlogTraceAspect(LogTracelogTrace){
returnnewLogTraceAspect(logTrace);
}
}
@Aspect의 정보를 기반으로 포인트컷, 어드바이스, 어드바이저를 생성하고 보관하는 것 담당
@Aspect의 정보를 기반으로 어드바이저를 만들고, @Aspect 어드바이저 빌더 내부 저장소에 캐시
캐시에 어드바이저가 이미 만들어져 있는 경우 캐시에 저장된 어드바이저를 반환
2. 어드바이저를 기반으로 프록시 생성
생성 : 스프링 빈 대상이 되는 객체를 생성(@Bean, 컴포넌트 스캔 모두 포함)
전달 : 생성된 객체를 빈 저장소에 등록하기 직전에 빈 후처리기에 전달
Advisor 빈 조회 : 스프링 컨테이너에서 Advisor 빈을 모두 조회
@aspect Advisor 조회 : @Aspect 어드바이저 빌더 내부에 저장된 Advisor를 모두 조회
프록시 적용 대상 체크 : 앞서 3-1, 3-2에서 조회한 Advisor에 포함되어 있는 포인트컷을 사용해서 해당 객체가 프록시를 적용할 대상인지 아닌지 판단, 이때 객체의 클래스 정보는 물론이고, 해당 객체의 모든 메서드를 포인트컷에 하나하나 모두 매칭, 그래서 조건이 하나라도 만족하면 프록시 적용 대상이 됨, 예를 들어서 메서드 하나만 포인트컷 조건에 만족해도 프록시 적용 대상이 됨
프록시 생성 : 프록시 적용 대상이면 프록시를 생성하고 프록시를 반환, 그래서 프록시를 스프링 빈으로 등록, 만약 프록시 적용 대상이 아니라면 원본 객체를 반환해서 원본 객체를 스프링 빈으로 등록
빈 등록 : 반환된 객체는 스프링 빈으로 등록
정리
@Aspect를 사용해서 애노테이션 기반 프록시를 매우 편리하게 적용, 실무에서 프록시를 적용할 때 대부분 이 방식 사용
애플리케이션 전반에 로그를 남기는 기능은 특정 기능 하나에 관심이 있는 기능이 아님, 애플리케이션의 여러 기능들 사이에 걸쳐서 들어가는 관심사
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.
하나의 프록시, 여러 Advisor 적용
Q. 예를 들어서 어떤 스프링 빈이 advisor1 , advisor2 가 제공하는 포인트컷의 조건을 모두 만족하면 프록시 자동 생성기는 프록시를 몇 개 생성할까?
프록시 자동 생성기 상황별 정리
advisor1의 포인트컷만 만족 프록시1개 생성, 프록시에advisor1만 포함advisor1,advisor2의 포인트컷을 모두 만족 프록시1개 생성, 프록시에advisor1,advisor2모두 포함advisor1,advisor2의 포인트컷을 모두 만족하지 않음 프록시가 생성되지 않음이후에 설명할 스프링 AOP도 동일한 방식으로 동작
정리
AnnotationAwareAspectJAutoProxyCreator덕분에 편리하게 프록시 적용 가능Advisor=Pointcut+AdviceAspect AOP
@Aspect애노테이션으로 매우 편리하게 포인트컷과 어드바이스로 구성되어 있는 어드바이저 생성 기능을 지원한다.참고
@Aspect는 관점 지향 프로그래밍(AOP)을 가능하게 하는 AspectJ 프로젝트에서 제공하는 애노테이션이다. 스프링은 이것을 차용해서 프록시를 통한 AOP를 가능하게 한다. 우선 이 애노테이션을 사용해서 스프링이 편리하게 프록시를 만들어준다고 생각하면 된다.
LogTraceAspect
@Aspect: 애노테이션 기반 프록시를 적용할 때 필요@Around("execution(* hello.proxy.app..*(..))")@Around의 값에 포인트컷 표현식을 넣음, 표현식은 AspectJ 표현식을 사용@Around의 메서드는 어드바이스 (Advice)가 됨ProceedingJoinPoint joinPoint: 어드바이스에서 살펴본MethodInvocation invocation과 유사한 기능, 내부에 실제 호출 대상, 전달 인자, 그리고 어떤 객체와 어떤 메서드가 호출되었는지 정보 포함 되어 있음AopConfig
@Import({AppV1Config.class, AppV2Config.class}): V1, V2 애플리케이션은 수동으로 스프링빈으로 등록해야 동작
@Bean logTraceAspect():@Aspect가 있어도 스프링 빈으로 등록LogTraceAspect에@Component애노테이션을 붙여서 컴포넌트 스캔을 사용해서 스프링 빈으로 등록ProxyApplication
@Aspect 프록시- 설명AnnotationAwareAspectJAutoProxyCreator)는Advisor를 자동으로 찾아와서 필요한 곳에 프록시를 생성하고 적용해준다고 했다.@Aspect를 찾아서 이것을Advisor로 만들어준다.@Aspect를Advisor로 변환해서 저장하는 기능도 한다.AnnotationAware(애노테이션을 인식하는)가 붙어 있는 것이다.자동 프록시 생성기는 2가지 일을 함
1.
@Aspect를 어드바이저로 변환해서 저장하는 과정@Aspect 빈 조회: 자동 프록시 생성기는 스프링 컨테이너에서@Aspect애노테이션이 붙은 스프링 빈을 모두 조회@Aspect어드바이저 빌더를 통해@Aspect애노테이션 정보를 기반으로 어드바이저 생성@Aspect기반 어드바이저 저장 : 생성한 어드바이저를@Aspect어드바이저 빌더 내부에 저장@aspect 어드바이저 빌더
BeanFactoryAspectJAdvisorsBuilder클래스@Aspect의 정보를 기반으로 포인트컷, 어드바이스, 어드바이저를 생성하고 보관하는 것 담당@Aspect의 정보를 기반으로 어드바이저를 만들고,@Aspect어드바이저 빌더 내부 저장소에 캐시2. 어드바이저를 기반으로 프록시 생성
@Bean, 컴포넌트 스캔 모두 포함)Advisor빈을 모두 조회@Aspect어드바이저 빌더 내부에 저장된Advisor를 모두 조회정리
@Aspect를 사용해서 애노테이션 기반 프록시를 매우 편리하게 적용, 실무에서 프록시를 적용할 때 대부분 이 방식 사용All reactions