스프링 AOP(Aspect Oriented Programming)
AOP는 Aspect Oriented Programming의 약자로 관점 지향 프로그래밍이라고 불린다. 관점 지향은 쉽게 말해 어떤 로직을 기준으로 핵심적인 관점, 부가적인 관점으로 나누어서 보고 그 관점을 기준으로 각각 모듈화하겠다는 것이다. 여기서 모듈화란 어떤 공통된 로직이나 기능을 하나의 단위로 묶는 것을 말한다.
예로들어 핵심적인 관점은 결국 우리가 적용하고자 하는 핵심 비즈니스 로직이 된다. 또한 부가적인 관점은 핵심 로직을 실행하기 위해서 행해지는 데이터베이스 연결, 로깅, 파일 입출력 등을 예로 들 수 있다.
AOP에서 각 관점을 기준으로 로직을 모듈화한다는 것은 코드들을 부분적으로 나누어서 모듈화하겠다는 의미다. 이때, 소스 코드상에서 다른 부분에 계속 반복해서 쓰는 코드들을 발견할 수 있는 데 이것을 흩어진 관심사 (Crosscutting Concerns)라 부른다.
AOP Advice
- Before Advice: Target 메소드 호출 전에 적용 (@Before 사용)
- After returning: Target 메소드 호출 후 적용 (@AfterReturnning 사용)
- After throwing: Target에서 예외 발생 후 적용 (@AfterThrowing 사용)
- After: Target 메소드 호출 후 예외 발생에 상관없이 적용 (@After 사용)
- Around: Target 메소드 호출 전/후 적용 (@Around 사용)
AOP Advice 우선순위
Spring-boot 적용 예시
build.gradle 적용
// https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-aop', version: '2.6.6'
AOP 설정
package com.sparta.week02.test;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;
@Aspect
@Component
public class LogAspect {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
// PointCut : 적용할 지점 또는 범위 선택
@Pointcut(value = "execution(public * com.sparta.week02.service..*(..))")
private void publicTarget() { }
// Advice : 실제 부가기능 구현부
@Around("publicTarget()")
public Object calcPerformanceAdvice(ProceedingJoinPoint pjp) throws Throwable {
logger.info("성능 측정을 시작합니다.");
StopWatch sw = new StopWatch();
sw.start();
// 비즈니스 로직 (메인 로직)
Object result = pjp.proceed();
sw.stop();
logger.info("성능 측정이 끝났습니다.");
logger.info("걸린시간: " + sw.getLastTaskTimeMillis() + "ms");
return result;
}
@Around("publicTarget() && args(a,b)" )
public Object around(ProceedingJoinPoint pjp, String a, String b) throws Throwable {
System.out.println("before" + a);
System.out.println("before" + b);
Object result = pjp.proceed(new Object[] {"테스트1","테스트2"});
System.out.println("after" + a);
System.out.println("after" + b);
return result;
}
@AfterReturning(value = "publicTarget()",returning = "returnValue")
public void afterReturn(Object returnValue)
{
System.out.println("afterReturn "+returnValue);
}
}
'CS' 카테고리의 다른 글
레디스(Redis)란? (0) | 2022.05.31 |
---|---|
CORS란 (0) | 2022.05.25 |
JWT(Json Web Token) (0) | 2022.05.23 |
HTTPS (0) | 2022.05.21 |
MVC란? (0) | 2022.04.03 |