..

[Spring Basic] 7. AOP

Table of contents

  • AOP가 필요한 상황
  • AOP 적용

AOP가 필요한 상황

모든 메소드의 호출 시간 측정하고 싶을때?

1000개의 메소드에 시간측정관련 코드를 전부 넣는다..? 사실상 매우 time-consuming하며 불필요한 작업

공통 관심 사항(cross-cutting concern) vs 핵심 관심 사항(core concern)

  • 공통 관심 사항 - 시간측정
  • 핵심 관심 사항 - 회원가입, 로그인

AOP 적용

AOP: Aspect Oriented Programming

공통 관심 사항(cross-cutting concern)과 핵심 관심 사항(core concern)을 분리하는것

시간측정로직을 한곳에 모아서 내가 원하는 곳에 적용하는것.

이걸 가능케 하는 기술이 AOP이다

Spring에서 AOP가 가능하게끔 기술을 제공해준다.

AOP 적용

aop/TimeTraceAop.java

@Aspect
public class TimeTraceAop {  
  
public Object execute(ProceedingJoinPoint joinPoint) throws Throwable{  
	long start = System.currentTimeMillis();  
	System.out.println("START: " + joinPoint.toString());  
	try{  
		Object object = joinPoint.proceed(); // 다음 메소드로 진행이 된다  
		return object;  
	} finally {  
		long finish = System.currentTimeMillis();  
		long timeMs = finish - start;  
		System.out.println("END: " + joinPoint.toString() + " " + timeMs + "ms");  
	}  
}
  • @Aspect 어노테이션이 필요함.

Spring Bean으로 등록하는 방법

1. @Component사용

aop/TimeTraceAop.java

@Aspect
@Component
public class TimeTraceAop {  
	...
}

2. 직접 Spring Bean 등록

SpringConfig.java

@Bean  
public TimeTraceAop timeTraceAop(){  
	return new TimeTraceAop();  
}

[!warning]+ 주의사항 해봤는데 작동안됨.. 다시 시도해봐야 할듯..

해당 공통관심사항을 어디에 적용할지 설정

@Around - 해당 패키지 하위에 다 적용시키는 것

@Aspect
public class TimeTraceAop {  

	@Around("execution(* ericbyeric.firstspringdemo..*(..))")
	public Object execute(ProceedingJoinPoint joinPoint) throws Throwable{  
		long start = System.currentTimeMillis();  
		System.out.println("START: " + joinPoint.toString());  
		try{  
			Object object = joinPoint.proceed(); // 다음 메소드로 진행이 된다  
			return object;  
		} finally {  
			long finish = System.currentTimeMillis();  
			long timeMs = finish - start;  
			System.out.println("END: " + joinPoint.toString() + " " + timeMs + "ms");  
		}  
	}
}


적용된 함수들이 호출 될때마다 joinPoint에서 조작 가능. 메소드들이 호출 될때마다 intercept가 걸리면서 작동하는 것이다.

AOP 내부 동작 방식 설명

HelloController가 memberService에 의존하고 있다. AOP가 적용이 되고 어디에 적용할지 정해지면 TimeTraceAop가 지정이 된다. 그러면 가짜 멤버 서비스가 생성이 된다 (called “프록시”)

그럼 스프링 컨테이너에 Bean을 등록할때 가짜 스프링빈을 앞에 세워 놓는다. HelloController가 프록시(가짜 멤버 서비스)를 호출하고 프록시가 끝나고 joinPoint.proceed()가 완료되야 그제서야 실제 memberService가 호출이 된다. (Proxy라는 기술이 사용된다. 이후에 공부해 볼것..)

전체 그림