[Spring] AOP 설정 및 Advice 적용(Pointcut > Before Advice)
AOP (관점지향 프로그래밍)
:: 기존의 코드를 수정하지 않고 원하는 기능의 관심사를 Target 객체의 JoinPoint(결합점)로 호출하여 결합하는 패러다임
:: 핵심로직은 아니지만 프로그래밍에 필요한 주변 로직을 관심사별로 분류하는 것이다. 관심사와 핵심 비즈니스 로직을 분리해서 별도의 코드로 작성하고 실행/컴파일 시 이를 결합하는 방식이다.
Advice 구분 (Pointcut)
- Before Advice :: Target의 JoinPoint 메서드를 호출하기 전에 실행되는 코드
- After Returning Advice :: 모든 실행이 정상적으로 이루어진 이후에 동작하는 코드
- After Throwing Advice :: 예외가 발생한 뒤에 동작하는 코드
- After Advice :: 정상적으로 실행되거나 예외가 발생했을 때의 구분없이 실행되는 코드
- Around Advice :: 메서드의 실행 자체를 제어할 수 있는 코드이며 직접 대상 메서드를 호출하고 결과나 예외 처리 가능
** Target에 어떤 Advice 를 적용할 것인지 어노테이션을 이용하여 설정할 수 있음(xml로도 가능)
** Pointcut은 Advice를 어떤 JoinPoint에 결합할 것인지 결정하는 설정이므로 Pointcut에 의해 기능을 사용할 수 있음
Pointcut 설정 주요 어노테이션
- @execution :: 메서드를 기준으로 Pointcut을 설정함 (aspectJ 표현식 사용)
- @within :: 특정 빈을 기준으로 Pointcut을 설정함
- this :: 주어진 인터페이스를 구현한 객체를 대상으로 Pointcut을 설정함
- @args :: 특정한 파라미터를 가지는 대상들만을 Pointcut을 설정함
- @annotation :: 특정한 어노테이션이 적용된 대상만을 Pointcut을 설정함
AOP기능은 보통 POJO클래스에 적용하고, AOP처리된 객체를 생성할 때 AspectJ 라이브러리를 사용하기 때문에 pom.xml에 해당 라이브러리를 추가해주어야 한다.
핵심 로직은 아니지만 꼭 필요한 로그 확인을 Advice 로 적용하기 위해 LogAdvice 클래스를 만들고 해당 클래스의 선언부에 @Aspect 어노테이션을 추가해준다. 스프링에게 이 클래스의 객체가 Aspect를 구현한 것임을 나타내주는 것이고 로그를 기록하는 메서드에 @Before 어노테이션을 적용하여 BeforeAdvice 를 구현한 메서드에 추가해준다.
@Before("execution(*com.coolcode.service.MemberService*.*(..))")
AOP설정의 경우 root-context.xml에 component-scan태그를 추가하여 Advice를 적용하려는 service패키지와 aop객체를 탐색할 수 있도록 한다. 이후 정상 적용되었다면 ServiceImpl에 LogAdvice가 함께 묶여서 proxy 객체를 생성하게 된다. 이후 service 변수는 ServiceImpl의 인스턴스가 아닌 Proxy 클래스의 인스턴스가 되고 이는 로그를 통해 확인 가능하다.