개발/Spring
[Spring] - AOP 예제
dongdev
2022. 2. 8. 00:08
AOP(Aspect Oriented Programming)는 관점 지향 프로그래밍이라 불린다.
공통 관심사(=횡단 관심사(Cross-Cutting Concerns))를 깔끔하게 처리하기 어려운 OOP를 보완하기 위해 개발되었다.
Spring에서 제공하는 Spring AOP는 프록시 기반으로 동작하며, 런타임 시점에 빈 후처리기(Bean Post Processor)를 통하여 기존 Bean 객체를 부가 기능이 더해진 프록시 객체로 바꿔친다. 또 프록시 기반으로 동작하기 때문에 메서드 실행 지점에만 AOP를 적용할 수 있다(프록시는 메서드 오버라딩 개념으로 동작). 마지막으로 Spring AOP는 스프링 컨테이너가 관리할 수 있는 Bean에만 AOP를 적용할 수 있다.
아래의 예제코드를 살펴보자.
build.gradle
implementation 'org.springframework.boot:spring-boot-starter-aop'
Controller
package hello.helloaop.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class AopContoller {
@GetMapping("/aop")
public String aopController() {
System.out.println("aopController 실행");
return "Hello Aop!";
}
}
AopConfig
package hello.helloaop.aop;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class AopConfig {
@Pointcut("@annotation(org.springframework.web.bind.annotation.GetMapping)")
public void getMapping() {}
// @Around("execution(* hello.helloaop.controller..*(..))")
// hello.helloaop.controller 패키지 아래로 모두 적용하겠다는 뜻
@Around("getMapping()")
public Object excute(ProceedingJoinPoint jointPoint) throws Throwable {
System.out.println("START: " + jointPoint.toString());
try {
return jointPoint.proceed(); //proceed() 기준으로 메소드 실행 전, 후로 나뉜다
} finally {
System.out.println("END: "+jointPoint.toString());
}
}
}
@Around 밑 메소드 부분이 Advice이다.
Advice는 '부가기능'을 뜻한다.
Advice 종류
- @Before (이전)
- 어드바이스 타겟 메소드가 호출되기 전에 어드바이스 기능을 수행
- @After (이후)
- 타겟 메소드의 결과에 관계없이(즉 성공, 예외 관계없이) 타겟 메소드가 완료 되면 어드바이스 기능을 수행
- @AfterReturning (정상적 반환 이후)
- 타겟 메소드가 성공적으로 결과값을 반환 후에 어드바이스 기능을 수행
- @AfterThrowing (예외 발생 이후)
- 타겟 메소드가 수행 중 예외를 던지게 되면 어드바이스 기능을 수행
- @Around (메소드 실행 전후)
- 어드바이스가 타겟 메소드를 감싸서 타겟 메소드 호출전과 후에 어드바이스 기능을 수행
이러한 Advice들이 적용될 수 있는 모든 위치를 Join point(조인 포인트)라 한다.
@Pointcut은 '어디에'라는 타겟을 정의해준다.
Advice(부가기능) 와 Pointcut(적용대상)을 합해 Advisor을 이룬다. 개념상 하나의 애스펙트(@Aspect)로 봐도된다.
포인트컷에 이름을 부여해서 따로 정의하는 대신 어드바이스 메소드 애노테이션에 포인트컷 표현식을 넣어서 적용할 수 도 있다.
@Around("@annotation(org.springframework.web.bind.annotation.GetMapping)")
모든 용어들을 정리하자면 아래와 같다
- Join point(조인 포인트): 어드바이스가 적용될 수 있는 모든 위치
- Pointcut(포인트컷): 조인 포인트 중에서 어드바이스가 적용될 위치를 선별
- Target(타겟): 어드바이스를 받는 객체, 포인트컷으로 결정
- Advice(어드바이스): 부가 기능
- Aspect(애스펙트): 어드바이스 + 포인트컷을 모듈화 한 것(@Aspect)
실행