AOP란 Aspect Oriented Programming의 약자로,
공통 관심 사항(cross-cutting concern)과 핵심 관심 사항(core concern)을 분리하는것이다.

전 시간에 했던 시간 측정 로직을 AOP를 적용시켜 수정해보자.
AOP패키지를 만들고 TimeTraceAop를 생성한다.
@Aspect 라는 어노테이션을 붙여 aop로 사용한다.
이제 여기에 시간 로직을 작성할 것이다.
@Around 를 작성해서 이 로직을 어디에 적용할지 정해준다.
아래 코드는 hello.hellospring 패키지 하위에 다 적용한다는 뜻이다.
@Aspect
@Component
public class TimeTraceAop {
@Around("execution(* hello.hellospring..*(..))")
public Object execute(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();
System.out.println("START" + joinPoint.toString()); // 메서드 이름 얻기
try {
return joinPoint.proceed(); //다음 메서드로 진행시킨다.
} finally {
long finish = System.currentTimeMillis();
long timeMs = finish - start;
System.out.println("END" + joinPoint.toString() + " " + timeMs + "ms"); // 메서드 이름 얻기
}
}
}
스프링 빈에 등록해줘야 하는데 위와같이 @Component 어노테이션을 붙여주는 방법이있고, 아래와 같이 SpringConfig에서 스프링 빈에 등록하는 방법이 있다. 직접 등록하는 방법이 직관적으로 aop 사용을 인지하기 좋아서 추천한다.
@Bean
public TimeTraceAop timeTraceAop() {
return new TimeTraceAop();
}
이제 서버를 띄워보면 START, END가 잘 뜨는것을 확인할 수 있다.

이제 전 시간에 문제가 되었던것들이 해결되었다.
AOP를 적용하기 전에는 의존관계대로 그냥 호출하였다.

이제 AOP를 적용해주면 프록시라는 가짜 memberService를 생성한다.
스프링 컨테이너에 등록할 때 가짜 스프링 빈을 세워두고 가짜가 끝나면 joinPoint.proceed()를 통해 진짜 memberService를 호출해준다.

AOP 적용 전, 후 그림은 아래와 같다.
