스프링 5 프로그래밍 입문/7. AOP 프로그래밍
7.2 프록시와 AOP
hp0724
2023. 9. 6. 00:11
실행시간을 출력하려면 메서드의 시작과 끝에서 시간을 구하고 두 시간의 차이를 출력
for 반복문의 경우
public class ImpeCalculator implements Calculator{
@Override
public long factorial(long num) {
long start = System.currentTimeMillis();
long result =1 ;
for (long i =1 ; i<=num; i++) {
result*=i;
}
long end = System.currentTimeMillis();
System.out.printf("ImpeCalculator.factorial(%d) 실행 시간=%d \n",
num,(end-start));
return result;
}
}
재귀 함수의 경우 함수가 실행할때마다 시간이 출력되니깐 메서드 실행 전후에 값을 구하는것이 좋을수 있다.
ImpeCalculator impeCal = new ImpeCalculator();
long start1 = System.curretTimeMillis();
long fourFactorial1 = implCal.factorial(4);
long end1 = System.curretTimeMillis();
System.out.printf("ImpeCalculator.factorial(4) 실행시간 = %d\n",(end1-start1)
실행시간을 밀리초 단위가 아니라 나노초 단위로 구해야 한다면
시간을 구하는 코드를 바꿔야 할것이다 .
그러나 기존 코드를 수정하지 않고 코드 중복도 피할수 있는 방법이 바로 프록시 객체이다.
public class ExeTimeCalculator implements Calculator{
private Calculator delegate;
public ExeTimeCalculator (Calculator delegate) {
this.delegate =delegate;
}
@Override
public long factorial(long num) {
long start = System.nanoTime();
long result = delegate.factorial(num);
long end = System.nanoTime();
System.out.printf("%s.factorial(%d) 실행시간 =%d\n",
delegate.getClass().getSimpleName(),num,(end-start));
return result;
}
}
public class MainProxy {
public static void main(String[] args) {
ExeTimeCalculator ttCal1 = new ExeTimeCalculator(new ImpeCalculator());
System.out.println(ttCal1.factorial(20));
ExeTimeCalculator ttCal2 = new ExeTimeCalculator(new ImpeCalculator());
System.out.println(ttCal2.factorial(20));
}
}
- 기존 코드를 변경하지 않고 실행 시간을 출력
- 실행 시간을 구하는 코드의 중복을 제거
- factorial() 기능 자체를 직접 구현하기보다는 다른 객체에 factorial() 실행을 위임
- 계산 기능 외에 다른 부가적인 기능을 실행 여기서는 실행 시간 측정
핵심 기능의 실행은 다른 객체에 위임하고 부가적인 기능을 제공하는 객체를 프록시
라고한다.
실제 핵심 기능을 실행하는 객체는 대상 객체라고 한다.
프록시의 특징은 핵심 기능은 구현하지 않는다는 점
여러 객체에 공통으로 적용할수 있는 기능을 구현한다.
공통 기능 구현과 핵심 기능 구현을 분리하는것이 AOP 의 핵심이다.
7.2.1 AOP
AOP
: Aspect Oriented Programming 의 약자로 , 여러 객체에 공통으로 적용할수 있는 기능을 분리해서 재사용성을 높여주는 프로그래밍 기법이다 .
관점 지향 프로그래밍으로 많이 번역 한다.
AOP 의 기본 개념은 핵심 기능에 공통 기능을 삽입하는것이다.
핵심 기능의 코드를 수정하지 않으면서 공통 기능의 구현을 추가하는 것
핵심 기능에 공통 기능을 삽입하는 방법
- 컴파일 시점에 코드에 공통 기능을 삽입하는 방법
- 클래스 로딩 시점에 바이트 코드에 공통 기능을 삽입하는 방법
- 런타임에 프록시 객체를 생성해서 공통 기능을 삽입하는 방법
AOP 주요 용어
용어 | 의미 |
---|---|
Advice | 언제 공통 관심 기능을 핵심 로직에 적용할지를 정의하고있다. |
Joinpoint | Advice를 적용 가능한 지점을 의미 |
메서드 호출 ,필드 값 변경 등이 Joinpoint에 해당 . | |
Pointcut | Joinpoint의 부분 집합으로서 실제 Advice가 적용되는 Joinpoint를 나타낸다. |
weaving | Advice를 핵심 로직 코드에 적용하는것을 weaving이라고 한다. |
Aspect | 여러 객체에 공통으로 적용되는 기능을 Aspect라고 한다. |
트랜잭션이나 보안 등 |
7.2.2 Advice의 종류
스프링은 프록시를 이용해서 메서도 호출 시점에 Aspect를 적용
종류 | 설명 |
---|---|
Before Advice | 대상 객체의 메서드 호출 전에 공통 기능을 실행 |
After Returning Advice | 대상 객체의 메서드가 익센션 없이 실행된 이후에 공통 기능 실행 |
After Throwing Advice | 대상 객체의 메서드를 실행하는 도중 익센셥이 발생한 경우에 공통 기능을 실행 |
After Advice | 익셉션 발생 여부에 상관없이 대상 객체의 메서드 실행 후 공통 기능을 실행 |
Around Advice | 대상 객체의 메서드 실행 전, 후 또는 익센셥 발생 시점에 공통 기능을 실행하는데 사용 |