코드를 짜다보니 갑자기 모든 메소드의 호출시간이 궁금해졌다(?)
그래서 메소드의 맨처음과 끝에 시간을 찍어 호출시간을 측정해봤다.
근데 1~2개면 모르겠는데 이걸 다하라고? 따로 메소드를 만들기도 복잡하고, 다 만들었는데 바꾸라하면 어캄...? 오늘은 야근이다...
public Long join(Member member) {
long start = System.currentTimeMillis();
try {
validateDuplicateMember(member); //중복 회원 검증
memberRepository.save(member);
return member.getId();
} finally {
long finish = System.currentTimeMillis();
long timeMs = finish - start;
System.out.println("join " + timeMs + "ms");
}
}
각각의 역할이나 책임에 따라 클래스를 분리했는데, 여러 클래스에서 반복 사용되는 코드가 있을 때 AOP를 적용할 수 있다. 즉, 공통 관심 사항을 묶어 하나의 메소드처럼 모듈화하는 것이 AOP.
=> 공통 관심 사항과 핵심 관심 사항을 분리할 수 있음.
유지보수할 때 이 프로그램은 AOP를 사용하고 있다고 인지하기 쉬워서 좋음.
@Bean
public TimeTraceAop timeTraceAop(){
return new TimeTraceAop();
}
@Component
@Aspect
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");
}
}
}
@Around("execution()")
: AOP를 적용시킬 메소드의 범위를 정할 수 있음.
controller가 service를 의존하는 관계로, controller에서 service 메소드들을 호출하여 동작한다.
memberService에 AOP를 적용시키면 스프링 컨테이너가 memberService를 올릴 때, 프록시 memberService를 올린다. memberController는 가상의 객체를 의존하고 있다가 AOP가 모두 실행되고 joinPoint.proceed()
하면 실제 memberService가 호출된다.