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"); } }
사진과 같은 개념으로 바꿔줘야 한다는 것이다.
- 컴포넌트로 스프링 빈 등록
@Aspect // AOP 로 쓰기 위해 등록 @Component public class TimeTraceAop { @Around("execution(* hello.hellospring..*(..))") // hellospring 패키지 하위 전부 적용 public Object execute(ProceedingJoinPoint joinPoint) throws Throwable { long start = System.currentTimeMillis(); System.out.println("START: " + joinPoint.toString()); try { // 변수 인라인 화 (Ctrl + Shift + Alt + T) return joinPoint.proceed(); } finally { long finish = System.currentTimeMillis(); long timeMs = finish - start; System.out.println("END: " + joinPoint.toString() +" " + timeMs + "ms"); } } }
AOP 적용 전 의존 관계
AOP 적용 후 의존 관계
스프링은 프록시라는 가짜 memberService를 만든다.
스프링 컨테이너에 스프링 빈을 등록할 때 진짜 스프링 빈이 아닌 가짜 스프링 빈을 앞세운다.
가짜 스프링 빈이 joinPoint.proceed()를 끝나면 그때 진짜 스프링 빈이 호출된다.
즉, memberController가 호출하는 것은 가짜 memberService 인 것이다.
AOP 가 적용되고 나서의 전체적 그림과
아래는 memberService를 복제해서 코드를 조작하는 프록시이다.
스프링 컨테이너에서 DI(의존성 주입이) 이라는 것이 있기에 AOP 기능을 사용할수 있는것이다