: 흩어진 관심사를 모듈화할 수 있는 프로그래밍 기법
OOP
를 보완하는 수단으로 프록시 패턴
을 사용한다.Aspect
Advice
와 어드바이스를 어디에 적용할지를 결정하는 PointCut
을 가지고 있다.Advice
Aspect
가 해야할 일들을 의미한다.PointCut
Advice
를 적용할 JoinPoint
를 선별하는 기능을 정의한 모듈을 의미한다.Target
JoinPoint
Advice
가 적용될 수 있는 위치를 의미한다.JoinPoint
는 메서드를 가리킨다 하여도 무방하다.AOP
를 적용할 수 있다.IoC
와 연동하여 엔터프라이즈 애플리케이션에서 가장 흔한 문제에 대한 해결책을 제공하는 것이 목적이다.: 기존 코드의 변경 없이 접근 제어 혹은 부가 기능을 추가할 수 있다.
의존성 추가
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
Aspect 정의
PointCut 정의
&&
||
!
Advice 정의
예제) 스프링 AOP를 사용하여 메서드 실행시간 로깅하기
// Aspect 에서 어디에 적용할지 표시할 용도로 사용된다.
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogExecutionTime {
}
// Service 클래스의 get 메서드나 @LogExecutionTime 애노테이션이 정의된 메서드의
// 실행시간을 로깅하는 Aspect 구현
@Slf4j
@Aspect
@Component
public class LogAspect {
@Pointcut("execution(* com..*.*Service.*(..))")
private void serviceLayer() {}
@Pointcut("execution(* get*(..))")
private void getMethod() {}
@Pointcut("serviceLayer() && getMethod()")
private void serviceLayerGetMethod() {}
@Around("serviceLayerGetMethod() || @annotation(LogExecutionTime)")
public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
Object proceed = joinPoint.proceed();
stopWatch.stop();
log.info(stopWatch.prettyPrint());
return proceed;
}
}