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 대상 객체의 메서드 실행 전, 후 또는 익센셥 발생 시점에 공통 기능을 실행하는데 사용