[Spring5입문] AOP 프로그래밍 기초

2021. 8. 9. 20:16CSE/Spring

1. 프록시와 AOP

- RecCalculator 클래스 : Calculator 인터페이스를 상속하고 팩토리얼 메소드를 재귀 방법으로 오버라이딩 한 클래스

- ImpeCalculator 클래스 : Calculator 인터페이스를 상속하고 팩토리얼 메소드를 for 문을 통해 오버라이딩 한 클래스

=> 이 두 클래스의 수정 없이, 코드 중복도 없이, 팩토리얼 메소드의 실행 시간을 구하려면?

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;
    }
}

=> ExeTimeCalculator 클래스를 통해 기존 코드를 변경하지 않고, 코드 중복 또한 피하면서 공통 기능을 구현할 수 있다.

=> 이 때, ExeTimeCalculator 클래스를 프록시락 부른다.

 

- 프록시 : 핵심 기능의 실행은 다른 객체에 위임하고, 대신 여러 객체에 공통적으로 적용할 수 있는 부가적인 기능을 제공하는 객체

- 대상 객체 : 실제 핵심 기능을 실행하는 객체

 

★ AOP의 핵심 : 공통 기능 구현과 핵심 기능 구현을 분리하는 것

 

2. AOP

- AOP (Aspect Oriented Programming) : 여러 객체에 공통적으로 적용할 수 있는 기능을 분리해서 재사용성을 높여주는 프로그래밍 기법
- AOP의 기본 개념 : 핵심 기능의 코드를 수정하지 않으면서 공통 기능의 구현을 추가하는 것

 

* 핵심 기능에 공통 기능을 삽입하는 방법 세 가지

  • 컴파일 시점에 코드에 공통 기능을 삽입하는 방법 => 스프링 AOP에서는 지원하지 않음, AOP 전용 도구 필요
  • 클래스 로딩 시점에 바이트 코드에 공통 기능을 삽입하는 방법 => //
  • 런타임에 프록시 객체를 생성해서 공통 기능을 삽입하는 방법 => 스프링 AOP에서 지원함

- 프록시 방식 : 프록시 객체를 생성하고, 실제 객체의 기능을 실행하기 전,후에 공통 기능을 호출한다.

- 스프링 AOP는 프록시 객체를 자동으로 만들어준다. 공통 기능을 구현한 클래스만 알맞게 구현하면 된다.

 

* AOP 주요 용어

  • Aspect : 여러 객체에 공통으로 적용되는 기능
  • Advice : 언제 공통 관심 기능을 핵심 로직에 적용할 지를 정의하고 있다.
  • Joinpoint : Advice를 적용 가능한 지점을 의미한다. 메서드 호출, 필드 값 변경 등이 이에 해당한다. 스프링은 프록시를 이용해서 AOP를 구현하기 때문에 메서드 호출에 대한 Joinpoint만 지원한다.
  • Pointcut : Joinpoint의 부분 집합으로서 실제 Advice가 적용되는 Joinpoint를 나타낸다. 스프링에서는 정규 표현식이나 AspectJ의 문법을 이용해서 이를 정의할 수 있다.
  • Weaving : Advice를 핵심 로직 코드에 적용하는 것

* 스프링에서 구현 가능한 Advice 종류

  • Before Advice : 대상 객체의 메서드 호출 전에 공통 기능을 실행
  • After Returning Advice : 대상 객체의 메서드가 익셉션 없이 실행된 이후에 공통 기능을 실행
  • After Throwing Advice : 대상 객체의 메서드를 실행하는 도중 익셉션이 발생한 경우에 공통 기능을 실행
  • After Advice : 익셉션 발생 여부에 상관없이 대상 객체의 메서드 실행 후 공통 기능 실행
  • Around Advice : 대상 객체의 메서드 실행 전, 후, 또는 익셉션 발생 시점에 공통 기능을 실행하는데 사용된다. 가장 널리 사용됨