[Spring] 스프링 AOP의 기본개념과 Advice의 종류 - 1
AOP란?
- 관점지향프로그래밍. 이라고 처음 듣고 배웠다. 맞긴 맞다. 다만 이렇게만 설명하면 어려워서 풀어서 이해를 하는 게 좋다.
- 프로그래밍을 포함해서 모든 일에는 중요한 일이 있고 덜 중요한 일이 있다. 스프링에서는 중요한 일을 “핵심기능” 이라고 보통 말하고 조금 덜 중요한 일을 “공통 기능”이라 말한다. 다만 조금 덜 중요할뿐 프로그래밍은 핵심기능과 공통기능이 모여서 완성되는 것이기 때문에 꼭 필요하다고 볼 수 있다.
- 이때 공통기능 구현을 도와주거나 여러곳에서 반복해서 사용하거나 어떤 핵심기능의 실행 전/후에 처리할일들이 있는데 이때 사용하는 것이 AOP이다.
- AOP의 기본개념은 핵심기능에 공통기능을 삽입하는 것!
왜 사용할까?
- 핵심기능은 말 그대로 핵심이므로 보통 난이도가 구현 난이도가 높아서 많은 고민과, 성능 등 여러가지를 생각해서 만들어야한다.
- 공통기능은 구현 난이도가 핵심기능보다 낮고 여러부분에서 사용한다. 그러므로 구현이 시간보다 많은 부분의 코드에 적용하는 시간이 더 많이 걸릴 수도 있다.
- 개인적인 판단으로는 객체지향 SOLID 원칙에서 O를 지키기 위해서 사용하면 참 좋은 방법이라고 생각한다. 공통적인 기능을 원하는 시점과 부분에 처리할 수 있기 때문이다.
AOP를 이용해 핵심기능에 공통 기능을 실행하는 3가지 방법
- 컴파일 시점에 코드에 공통 기능을 삽입
- 클래스 로딩 시점에 바이트 코드에 공통 기능을 삽입
- 런타임에 프록시 객체를 생성해서 공통 기능을 삽입
- 1,2 는 스프링AOP에서는 지원하지 않고 AspectJ와 같이 AOP 전용 도구를 사용해야한다.
- 스프링은 프록시를 이용한 3번 방법이다.
Proxy패턴
- 스프링 AOP를 얘기할 때 프록시패턴을 빼놓고 얘기할 수는 없다. 스프링에서 사용하는 AOP 패턴 자체가 프록시패턴을 사용하기 때문이다.
- 핵심기능의 실행은 다른 객체에 위임하고 부가적인 기능을 제공하는 객체를 프록시라고 부른다.
- 오른쪽 그림처럼 스프링 AOP를 사용하면 실제 객체를 실행하기 전에 공통 기능을 호출한다.
- 프록시 -> 공통기능 -> 핵심기능 -> 공통기능의 순서로 실행한다.
AOP의 주요 용어
- Advice: 언제 어느 시점에(메서드 실행 전/후,전후모두 등) 공통기능을 핵심기능에 적용할지를 지정한다.
- Joinpoint: Advice가 적용 가능한 지점을 의미한다. 메서드 호출, 필드값 변경 등이 Joinpoint에 해당한다.
- Pointcut: 특정 조건에 의해서(정규표현식이나 AspectJ의 문법 등) 필터링 된 Joinpoint라고 말할 수 있다. 수 많은 Joinpoint 중에서 특정 메서드만 공통기능을 수행시키기 위해서 필요하다.
위 3가지가 스프링에서 AOP를 사용할때 제일 중요한 개념이다. 육하원칙처럼 설명하자면, Advice는 언제!, Joinpoint는 어디서!, Pointcut은 누가! 라고 말할 수 있다고 본다. 이 외에도
- Weaving: Advice를 핵심 로직 코드에 적용하는 것을 weaving이라고 한다.
- Aspect: 여러 객체에 공통으로 적용되는 기능을 Aspect라고 한다. 트랜잭션이나 보안 등이 Aspect의 좋은 예이다. 그리고 스프링에서 AOP를 사용할때 @Aspect 어노테이션을 붙여서 사용한다.
Advice의 종류
위에서 Advice는 언제 적용할지 시점을 얘기한다고 했는데 그 시점이 다양하게 존재한다.
- Before Advice: 대상 객체(핵심기능을 실행하는 객체)의 메서드 호출 전에 공통기능을 실행한다.
- After Returning Advice: 대상 객체의 메서드가 익셉션 없이 실행된 이후에 공통기능을 실행한다.
- After Throwing Advice: 대상 객체의 메서드를 실행하는 도중 익셉션이 발생한 경우에 공통 기능을 실행한다.
- After Advice: 익셉션 발생 여부에 상관없이 대상 객체의 메서드 실행 후 공통 기능을 실행한다.(try catch finally와 비슷)
- Around Advice: 대상 객체의 메서드 실행 전/후 또는 익셉션 발생 시점에 공통 기능을 실행하는데 사용된다.
Leave a comment