반응형
애스펙트(Aspect)
- 여러 객체에 공통으로 적용되는 기능 (공통 기능)
- 어드바이스(Advice) + 포인트 컷(PointCut)을 모듈화 하여 애플리케이션에 포함되는 횡단 기능(Cross-cutting Concerns**)**
- 여러 개의 어드바이스와 포인트컷이 함께 존재
조인 포인트(join point)
위 이미지의 S는 메서드 실행 전의 포인트이고, E는 메서드 실행 후의 포인트이다. S와 같은 포인트를 어드바이스가 적용될 조인 포인트라고 한다.
- 클래스 초기화, 객체 인스턴스화, 메서드 호출, 필드 접근, 예외 발생과 같은 애플리케이션 실행 흐름에서의 특정 포인트를 의미한다.
- 애플리케이션에 새로운 동작을 추가하기 위해 조인포인트에 관심 코드(Aspect code)를 추가할 수 있다.
- 횡단 관심은 조인포인트 전/후에 AOP에 의해 자동으로 추가된다.
- 조인 포인트는 추상적인 개념으로 AOP를 적용할 수 있는 모든 지점이라 해석할 수 있다.
- 스프링 AOP는 프록시 방식을 사용하여 조인포인트가 항상 메서드의 실행 지점으로 제한된다.
- 어드바이스 적용이 필요한 곳은 애플리케이션 내에 메서드를 갖는다.
어드바이스(Advice)
- 조인 포인트에서 수행되는 코드를 의미
- Aspect를 언제 핵심 코드에 적용할지 정의
- 시스템 전체 Aspect에 API 호출 제공
포인트컷(PointCut)
- 조인 포인트 중에서 어드바이스가 적용될 위치를 선별하는 기능
- AspectJ 표현식을 사용하여 지정
- 프록시를 사용하는 스프링 AOP는 메서드 실행 지점만 포인트컷으로 선별 가능하다.
위빙(Weaving)
- 포인트컷으로 결정한 타겟의 조인 포인트에 어드바이스를 적용하는 것으로 Advice를 핵심 코드에 적용하는 것이다.
- 핵심 기능 코드에 영향을 주지 않고 부가 기능을 추가할 수 있다.
- AOP 적용을 위해 Aspect 객체에 연결한 상태를 뜻한다.
- 컴파일 타임(AspectJ compooiler)
- 로드 타임
- 런타임
- 스프링 AOP는 런타임, 프록시 방식
AOP 프록시(Proxy)
- AOP 기능을 구현하기 위해 만든 프록시 객체
- 스프링에서 AOP 프록시는 JDK 동적 프록시 또는 CGLIB 프록시를 뜻함
타겟(Target)
- 핵심 기능을 담고 있는 모듈로 타겟은 부가기능을 부여할 대상이 된다.
- Advice를 받는 객체이고 포인트컷으로 결정된다.
어드바이저(Advisor)
- 하나의 어드바이스와 하나의 포인트컷으로 구성된다.
- 스프링 AOP에서만 사용되는 특별한 용어이다.
어드바이스(Advice)
- Aspect를 언제 핵심 코드에 적용할지를 정의
- 특정 조인 포인트에서 애스펙트에 의해 취해지는 조치
Advice 순서
기본적으로 어드바이스는 순서를 보장하지 않는다.
순서를 지정하기 위해서는 @Aspect 적용 단위로 org.springframework.core.annotation.@Order 어노테이션을 적용해야 한다.
- 어드바이스 단위가 아닌 클래스 단위로 적용할 수 있다.
- 하나의 애스펙트에 여러 어드바이스가 존재하면 순서를 보장받을 수 없다.
애스펙트를 별도의 클래스로 분리해야 한다.
Advice 종류
Before
- 조인 포인트 실행 이전에 실행한다.
- 타겟 메서드가 실행되기 전에 처리해야 할 필요가 있는 부가 기능을 호출하기 전에 공통 기능을 실행한다.
- Before Advice 구현한 메서드는 일반적으로 리턴 타입이 void이다.
- 리턴 값을 가지고 있더라도 실제 Advice 적용 과정에 영향을 끼치지 않는다.
- 주의할 점은 메서드에서 예외를 발생시킬 경우 대상 객체의 메서드가 호출되지 않게 된다는 점이다.
@Before("hello.aop.order.aop.Pointcuts.orderAndService()")
public void doBefore(JoinPoint joinPoint) {
log.info("[before] {}", joinPoint.getSignature());
}
AfterReturning
- 조인 포인트가 정상 완료된 후 실행한다.
- 메서드가 예외 없이 실행된 이후에 공통 기능을 실행한다.
@AfterReturning(value = "hello.aop.order.aop.Pointcuts.orderAndService()", returning = "result")
public void doReturn(JoinPoint joinPoint, Object result) {
log.info("[return] {} return={}", joinPoint.getSignature(), result);
}
AfterThrowing
- 메서드가 예외를 던지는 경우에 실행한다.
- 메서드를 실행하는 도중에 예외가 발생하는 경우 공통 기능을 실행한다.
@AfterThrowing(value = "hello.aop.order.aop.Pointcuts.orderAndService()", throwing = "ex")
public void doThrowing(JoinPoint joinPoint, Exception ex) {
log.info("[ex] {} message={}", joinPoint.getSignature(), ex.getMessage());
}
After (finally)
- 조인 포인트의 동작(정상 종료 또는 예외 발생)과는 상관없이 실행한다.
- 메서드 실행 후 공통 기능을 실행한다.
- 일반적으로 리소스를 해제하는 데 사용한다.
Around
- 메서드 호출 전후에 수행하며 가장 강력한 어드바이스이다.
- 조인 포인트 실행 여부 선택, 반환 값 변환, 예외 변한 등이 가능하다.
- joinPoint.proceed() : 조인 포인트 실행 여부 선택
- joinPoint.proceed(args[]) : 전달 값 변환
- 반환 값 변환
- 예외 변환
- 메서드 실행 전과 후, 예외 발생 시점에 공통 기능을 실행한다.
- 어드바이스의 첫 번째 파라미터는 ProceedingJoinPoint를 사용해야 한다.
- proceed()를 통해 대상을 실행한다.
- proceed()는 여러 번 실행할 수 있다.
Around
Around는 가장 강력한 어드바이스로 대부분의 기능을 제공한다. 하지만, 타겟 등 고려해야 할 사항이 있을 때 정상적으로 작동이 되지 않는 경우가 있다.
- @Before, @After와 같은 어드바이스는 기능은 적지만 원하는 대로 작동되고 코드도 단순하다.
- 좋은 설계는 @Around만 사용해서 모두 해결하는 것보다는 제약을 가지더라도 실수를 방지하는 것이 좋다.
- 제약을 두면 문제 자체가 발생하지 않게 하며, 역할이 명확해진다.
반응형
'프레임워크(Framework) > Spring' 카테고리의 다른 글
[Spring MVC] 스프링 MVC란 무엇인가? - 스프링 MVC 구조 이해 (0) | 2022.11.10 |
---|---|
[Spring] 스프링 AOP 포인트컷(Pointcut) 표현식 정리 (0) | 2022.11.09 |
[Spring] 스프링 조회한 빈(Bean)이 2개 이상인 경우 문제 해결 방법 (1) | 2022.11.07 |
[Spring] 롬복(Lombok)을 이용한 의존관계 주입 방법 (0) | 2022.11.06 |
[Spring] 스프링 컴포넌트 스캔(Component Scan) 정리 (0) | 2022.11.05 |