August
13th,
2021
스프링 AOP 적용
앞서 간단하게 프록시 패턴을 통해 적용했던 AOP를 스프링 AOP로 변경해보자.
package me.cjkim.demoSpring51;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
@Component //빈으로 등록
@Aspect
public class PerfAspect {
@Around("execution(* me.cjkim..*.EventService.*(..))") //me.cjkim 패키지 하위 모든 클래스 중 EventService 클래스의 모든 메소드에 적용
public Object logPerf(ProceedingJoinPoint pjp) throws Throwable{
long begin = System.currentTimeMillis();
Object retVal = pjp.proceed();
System.out.println(System.currentTimeMillis() - begin);
return retVal;
}
}
@Aspect
를 통해 해당 클래스는 Aspect라고 명시해주었다. logPerf
메소드는 advice를 맡고 있으며, 횡단 관심사로 어떤 일을 진행할지를 정의하였다. @Around
어놑이션을 통해 포인트 컷의 실행 전 후에 적용된다는 것을 알 수 있으며, 어노테이션의 매개변수로 포인트 컷을 지정, 즉 조인 포인트를 정의하였다. 만일 특정 메소드는 적용하고 싶지 않다면, 어노테이션을 이용해서 제외시킬 수 있다.
package me.cjkim.demoSpring51;
import java.lang.annotation.*;
@Documented // JavaDoc이 어노테이션의 존재를 표기하도록 지정
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.METHOD) // 메소드만 타켓으로 지정한다는 것을 명시
public @interface PerfLogging {
}
PerfLogging
이라는 어노테이션을 만들었다. 여기서 주의해야 할 점은 RetentionPolicy
값은 클래스 이상으로 지정해야 한다는 점이다(기본 값은 클래스이다).
RetentionPolicy
는 어노테이션 정보를 언제까지 유지할 것인지에 대한 정보이다. 클래스까지 정의하면 클래스 파일까지 유지하겠다는 의미이며, 컴파일 후에도 어노테이션 정보가 남아 있다. 그런데 만일 Source로 변경하게되면, 컴파일 하고나면 어노테이션 정보가 사라진다. 또 런타임까지는 유지할 필요는 없기에 클래스로 지정해두자.
그리고 어드바이스를 지정하고 싶은 메소드에만 어노테이션을 추가한 뒤, aspect의 @Around
어노테이션의 설정 값을 아래와 같이 변경하자.
package me.cjkim.demoSpring51;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
@Component //빈으로 등록
@Aspect
public class PerfAspect {
@Around("@annotation(PerfLogging)")
public Object logPerf(ProceedingJoinPoint pjp) throws Throwable{
long begin = System.currentTimeMillis();
Object retVal = pjp.proceed();
System.out.println(System.currentTimeMillis() - begin);
return retVal;
}
}
위와 같이 설정한 후 실행하면 내가 어노테이션을 지정한 메소드에만 해당 기능이 적용되는 것을 볼 수 있다.
포인트 컷 정의
@PointCut(표현식)
- 주요 표현식
- execution
- @annotation
- bean
-
포인트컷 조합 : &&, , ! 등 연산자등을 이용하여 여러 포인트컷 지정 가능
어드바이스 정의
@Before
: 실행 직전@AfterReturning
: 성공적으로 실행 후@AfterThrowing
: 예외 발생 후@Around
: 실행 전 후
참고 자료