a. aspect 만들기
@Slf4j
@Aspect
/**
* 애스팩트: 어드바이스와 포인트컷을 하나로 묶은 모듈
*/
public class AspectPractice {
// 포인트컷
// 어드바이스 위치
}
- AOP 등록
@Configuration
public class WebConfig {
@Bean
public AspectPractice getAspectPracticeAop() {
return new AspectPractice();
}
}
b. 패키지 범위 기반 포인트컷 만들기
/**
* 포인트컷: 서비스 패키지 기반
*/
@Pointcut("execution(* com.standard.sparta.service..*(..))")
private void serviceLayer() {}
c. 어드바이스 종류 살펴보기
1. Before
/**
* 어드바이스: @Before
* 메서드 실행 전에 수행되는 로직을 처리할때 사용합니다.
*/
@Before("serviceLayer()")
public void beforeMethod(){
log.info("::: BEFORE 실행 :::");
}
2. AfterReturning
/**
* 어드바이스: @AfterReturning
* 메서드가 정상적으로 반환된 후에 실행됩니다.
* 예외가 발생하지 않고 정상적으로 결과값을 반환했을때만 동작합니다.
* @param result 성공시 반환값
*/
@AfterReturning(pointcut = "serviceLayer()", returning = "result")
public void afterReturningMethod(Object result) {
// result 에 대한 작업을 수행할 수 있겠죠?
log.info("::: AFTER RETURNING :::");
}
3.AfterThrowing
/**
* 어드바이스: @AfterThrowing
* 메서드 실행 중 예외가 발생했을 때만 실행됩니다.
* @param joinPoint 조인포인트
* @param ex 발생한예외 객체
*/
@AfterThrowing(pointcut = "serviceLayer()", throwing = "ex")
public void afterThrowingMethod(JoinPoint joinPoint, Throwable ex) {
// 서비스에서 발생한 예외 ex.getMessage() <- 예외 조작 가능
log.info("::: AFTER THROWING :::");
}
4. After
/**
* 어드바이스: @After
* 메서드가 정상적으로 실행되던 예외가 발생하던 메서드가 완료된 후에 항상 실행됩니다.
*/
@After("serviceLayer()")
public void afterMethod(JoinPoint joinPoint) {
log.info("::: AFTER :::");
}
5. Around
/**
* 어드바이스: 가장 강력한 어드바이저, 전체 흐름을 제어할 수 있습니다.
* @param joinPoint
* @return
* @throws Throwable
*/
@Around("serviceLayer()") // 어노테이션 기반으로 포인트컷 설정
public Object aroundMethod(ProceedingJoinPoint joinPoint) throws Throwable {
log.info("::: BEFORE :::");
try {
Object result = joinPoint.proceed();
System.out.println(result);
log.info("::: AFTER RETURNING :::");
return result;
} catch (Exception e) {
log.info("::: AFTER THROWING :::");
throw e;
} finally {
log.info("::: AFTER :::");
}
}
d. 패키지 범위 기반 어드바이스 적용
/**
* 어드바이스: 패키지 범위 기반
*/
@Around("serviceLayer()")
public Object advicePackage(ProceedingJoinPoint joinPoint) throws Throwable {
long startTime = System.currentTimeMillis();
try {
return joinPoint.proceed();
} finally {
long endTime = System.currentTimeMillis();
long executionTime = endTime - startTime;
log.info("::: ExecutionTime: {}ms", executionTime);
}
}
e. 어노테이션 범위 기반 어드바이스 적용
1. 어드바이스 생성
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TrackTime {
}
2. 포인트컷 생성
/**
* 포인트컷: 어토네이션 기반
*/
@Pointcut("@annotation(com.standard.sparta.aop.annotation.TrackTime)")
private void trackTimeAnnotation() {}
3. 어드바이스
/**
* 어드바이스: 어노테이션 범위 기반
*/
@Around("trackTimeAnnotation()")
public Object adviceAnnotation(ProceedingJoinPoint joinPoint) throws Throwable {
//측정 시작
long startTime = System.currentTimeMillis();
try {
Object result = joinPoint.proceed();
return result;
} finally {
// 측정 완료
long endTime = System.currentTimeMillis();
long executionTime = endTime - startTime;
log.info("::: ExecutionTime: {}ms", executionTime);
}
}
'Spring' 카테고리의 다른 글
[Spring] 소셜로그인 연동 | 카카오 로그인 | 카카오 사용자 정보 가져오기 | 카카오 사용자 정보로 회원가입 구현 (0) | 2024.09.18 |
---|---|
[Spring] Controller 테스트 코드 작성하기 (0) | 2024.09.13 |
[Spring] 단위 테스트 | 테스트 코드 작성법 (0) | 2024.09.10 |
[Spring] 스프링 예외처리 통일 | 스프링 HttpStatus 반환 통일 | 스프링 에러 통일 (3) | 2024.09.05 |
[Spring] JWT 인증 처리 로직 클래스 설계 (0) | 2024.08.29 |