만약 사이트 이용고객중 이용시간으로 순위를 매겨 Top5에게 경품을 주기위해 모든 고객의 사이트 이용시간이 필요하다고 하자 우리는 어떻게 고객의 사이트 이용시간을 구할수있을까?
우선 Aop에 대해 알아보자면 Asepect Oriented Programming의 약자로 관점 지향 프로그래밍을 뜻한다. 우리가 배웠던 객체 지향 프로그래밍과 유사한 말이면서 객체가 관점으로 바뀌었는데 이것은 어떤 로직을 기준으로 핵심적인 관점, 부가적인 관점으로 나누어보고 그 관점 기준으로 각각 모듈화 하는 프로그래밍이라는 뜻이다.
위 사진을 토대로 이해해보자면 앞서 우리가 고민한 사이트 이용고객의 사이트 이용시간을 구하기위해 측정시작시간과 측정종료시간을 체크하여 해당 시간을통해 이용시간을 DB에 차곡차곡 누적시킴을 통해 구한다고 한다면 우리는 부가기능에 측정시간을 측정하는 로직을 구현하여 AOP를 사용하여 모든 비즈니스로직을 핵심기능으로 보고 적용시킨다면? 전체적인 코드의 수정없이 해당 기능을 구현할수있다.
Spring에서는 해당 Aop를 에너테이션을 통해 쉽게 사용할수있는데 해당 에너티에션을 정리해보자면
@Aspect
: Spring Bean class에만 적용가능하며 Aop선언
@Around
: '핵심기능' 수행 전과 후 (@Before + @After)
@Before
: '핵심기능' 호출 전 (ex. Client 의 입력값 Validation 수행)
@After
: '핵심기능' 수행 성공/실패 여부와 상관없이 언제나 동작 (try, catch 의 finally() 처럼 동작)
@AfterReturning
: '핵심기능' 호출 성공 시 (함수의 Return 값 사용 가능)
@AfterThrowing
: '핵심기능' 호출 실패 시. 즉, 예외 (Exception) 가 발생한 경우만 동작 (ex. 예외가 발생했을 때 개발자에게 email 이나 SMS 보냄)
만약 어느 한 서비스 레이어에서 어떤 메서드는 Around
를 어떤메서드에서는 Before
만 사용하고싶다면? 우리의 Spring은 이 또한 포인트컷 Expression
을 통해 지원하고있다.
execution(modifiers-pattern? return-type-pattern declaring-type-pattern? method-name-pattern(param-pattern) throws-pattern?)
포인트컷의 표현식은 위와 같다.
modifiers-pattern
: public, private, 등
return-type-pattern
: void, String, List<String>, 등
declaring-type-pattern
: 클래스명(패키지명필요) .* 모든패키지의 클래스 적용, .. 패키지 및 하위패키지의 모든 클래스 적용
method-name-pattern(param-pattern)
:
- function() 해당함수에만 적용, function* 함수명으로 시작하는 모든 함수에 적용
- 파라미터 패턴(param-pattern)
- (com.sparta.myselectshop.dto.FolderRequestDto) - FolderRequestDto 인수 (arguments) 만 적용
- () - 인수 없음
- (*) - 인수 1개 (타입 상관없음)
- (..) - 인수 0~N개 (타입 상관없음)
@Component
@Aspect
public class Aspect {
@Pointcut("execution(* com.sparta.myselectshop.controller.*.*(..))")
private void forAllController() {}
@Pointcut("execution(String com.sparta.myselectshop.controller.*.*())")
private void forAllViewController() {}
@Around("forAllContorller() && !forAllViewController()")
public void saveRestApiLog() {
...
}
@Around("forAllContorller()")
public void saveAllApiLog() {
...
}
}
조건식을 사용하여 포인트 컷간의 조건을 걸어 사용할수도있다.