// 측정 시작 시간
long startTime = System.currentTimeMillis();
try {
// 핵심기능 수행
// 로그인 되어 있는 회원 테이블의 ID
Long userId = userDetails.getUser().getId();
Product product = productService.createProduct(requestDto, userId);
// 응답 보내기
return product;
} finally {
// 측정 종료 시간
long endTime = System.currentTimeMillis();
// 수행시간 = 종료 시간 - 시작 시간
long runTime = endTime - startTime;
// 수행시간을 DB 에 기록
...
}
위 문제점들 외에 여러가지 단점들을 보완하기 위해 AOP를 통해 부가기능을 모듈화를 했다.
- AOP
서로 다른 관점으로 핵심기능은 핵심끼리, 부가기능은 부가끼리 설계하고 구현하자! 이런 생각에서 나오게 된 프로그래밍
핵심기능을 호출하는 어떤 녀석이 있는데, 그 녀석이 핵심기능을 바로 호출하는 것이 아니라 중간에 프록시라는 객체가 생성이 되고, 프록시가 핵심기능을 호출하도록 한다. 프록시는 결국은 부가기능의 역할을 한다.
시퀀스 다이어그램 (Sequence Diagram)
AOP 적용 전
AOP 적용 후
디스패처서블릿이 /api/products에 해당되는 함수를 찾아서 Controller에 요청을 보낼 때, AOP Proxy가 부가기능을 하기 위해서 Controller인 척 하면서 중간에서 가로챈다.
중요한건 디스패처서블릿은 마치 Controller로 호출할 때랑 동일하게 호출하고, 동일하게 결과를 받는다는 것이다.
호출되는 함수의 input, output 이 완전 동일
"joinPoint.proceed()" 에 의해서 원래 호출하려고 했던 함수, 인수(argument) 가 전달됨
→ createProduct(requestDto)
스프링 서버가 기동될 때
@Aspect
어드바이스 종류
포인트컷
execution(modifiers-pattern? return-type-pattern declaring-type-pattern?
method-name-pattern(param-pattern) throws-pattern?)
@Around("execution(public * com.sparta.springcore.controller..*(..))")
public Object execute(ProceedingJoinPoint joinPoint) throws Throwable { ... }
modifiers-pattern
return-type-pattern
String
>, *declaring-type-pattern
method-name-pattern(param-pattern)
@Pointcut
포인트컷 재사용 가능
포인트컷 결합 (combine) 가능
@Component
@Aspect
public class Aspect {
@Pointcut("execution(* com.sparta.springcore.controller.*.*(..))")
private void forAllController() {}
@Pointcut("execution(String com.sparta.springcore.controller.*.*())")
private void forAllViewController() {}
@Around("forAllContorller() && !forAllViewController")
public void saveRestApiLog() {
...
}
@Around("forAllContorller()")
public void saveAllApiLog() {
...
}
}
Service가 아무리 Repository를 바로 호출하더라도 Controller에서 Repository를 바로 호출하지 말아야한다. 그래야 AOP라는 장점을 사용할 수 있다.
만약 모든 Service에 AOP를 적용하도록 구현해 놓았다면 부가 기능이 적용되지 않을 것이다.
이제 얼마 후에 실전 프로젝트가 시작하는데, 느낌적으로 스프링 AOP를 활용하게 될 것 같다.
잘 기억해두었다가 멋지게 사용해보면 좋겠다.