AOP
관점 지향 프로그래밍 - Aspect Oriented Programming
AOP : 공통적인 부분을 스프링이 도와서 처리해준다는 개념.
그런데 공통적인 부분의 범위가 어느정도 일까 ?
완전히 전반적인 프로젝트 공통적인 기능의 대표적인 예시는 다음과 같다.
>> 인증
이런것들은 필터 또는 인터셉터로 처리 하는게 더 적합하다.
하지만,
특정 타이밍 / 시점 / 컨트롤러 에 대해서 원하는 작업 (기능) 을 부여 하고 싶다면 ?
이런것들은 AOP 개념을 활용하여 처리 하는게 좋다.
(필터나 인터셉터 보다 조금 더 똑똑하게 처리 하고 싶을 때)
예시)
1) 로깅
특정 함수가 호출 되었을 때 자세한 로깅을 남기고 싶을 때.
2) 트랜잭션
Spring MVC 프로젝트를 구현할 때, @Transactional 어노테이션을 많이 사용 하게 된다.
이 어노테이션을 사용 할 때, 내부적으로 AOP 기법을 사용 하여,
트랜잭션이 시작하는 부분과 끝나는 부분의 처리를 AOP가 대신 처리 하게 된다.
3) 인증
특정 영역에 대한 추가적인 인증이 필요 할 때.
ex)
어떠한 lock을 걸어서 사용자가 하나의 리소스에 대해 중복으로 접근 할 수 없도록 할때.
[ 정리 ]
OOP 로 처리 하기에 다소 까다로운 부분을 AOP 라는 처리 방식을 도입 하여,
손쉽게 공통 기능을 추가 / 수정 / 삭제 할 수 있도록 한다.
AOP의 기본 개념
1)
Aspect
특정 관심 (관점) 에 대해서 모듈화 한것을 Aspect 라고 한다.
Aspect 생성 하기.
package org.xyz;
import org.aspectj.lang.annotation.Aspect;
@Aspect
@Component // Component를 붙인 것은 해당 Aspect를 스프링의 Bean으로 등록해서 사용하기 위함
public class UsefulAspect {
}
2)
Advice
단어 뜻 그대로 보면 도움 / 조언 이라는 뜻이다.
AOP가 동작 하면서 실제로 동작 하는 기능 (로깅 / 트랜잭션 / 인증) 을 뜻한다.
Before Advice
dataAccessOperation()이라는 미리 정의된 포인트 컷의 바로 이전에 doAccessCheck가 실행 된다.
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
public class BeforeExample {
@Before("com.xyz.myapp.CommonPointcuts.dataAccessOperation()")
public void doAccessCheck() {
// ...
}
}
After Returning Advice
dataAccessOperation()라는 미리 정의된 포인트컷에서 return이 발생된 후 실행 된다.
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterReturning;
@Aspect
public class AfterReturningExample {
@AfterReturning("com.xyz.myapp.CommonPointcuts.dataAccessOperation()")
public void doAccessCheck() {
// ...
}
}
Arround Advice
businessService()라는 포인트컷의 전 / 후에 필요한 동작을 추가 한다.
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.ProceedingJoinPoint;
@Aspect
public class AroundExample {
@Around("com.xyz.myapp.CommonPointcuts.businessService()")
public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
// start stopwatch
Object retVal = pjp.proceed();
// stop stopwatch
return retVal;
}
}
3)
Join Point
프로그램이 진행 될 때,
예를 들어,
A 라는 클래스가 생성될 수도 있고,
A 라는 클래스에서 B 라는 메서드가 호출 될 수 있고,
B라는 메서드에서 C라는 반환값이 return 될 수도 있고,
또 다음 D 라는 메서드가 호출 될 수도 있다.
이러한 모든 프로그램의 흐름에 있어서 특정 시점에 Aspect를 넣어 줄 수 있는 포인트를
조인 (연결) 가능한 포인트라 해서 Join Point 라고 한다.
4)
Pointcut
Join Point 중에서 해당 Aspect를 적용할 대상을 뽑을 특정 조건식.
Pointcut 선언 하기.
package org.xyz;
import org.aspectj.lang.annotation.Aspect;
@Aspect
@Component // Component를 붙인 것은 해당 Aspect를 스프링의 Bean으로 등록해서 사용하기 위함
public class UsefulAspect {
@Pointcut("execution(* transfer(..))")
private void anyOldTransfer() {}
}
- 해당 Aspect의 Advice (실행할 액션)이 적용될 Join point를 찾기 위한 패턴 또는 조건 생성
- ("execution(* transfer(..))") 은 포인트 컷 표현식이라고 부른다.
Pointcut 결합 하기.
package org.xyz;
import org.aspectj.lang.annotation.Aspect;
@Aspect
@Component // Component를 붙인 것은 해당 Aspect를 스프링의 Bean으로 등록해서 사용하기 위함
public class UsefulAspect {
@Pointcut("execution(public * *(..))")
private void anyPublicOperation() {} //public 메서드 대상 포인트 컷
@Pointcut("within(com.xyz.myapp.trading..*)")
private void inTrading() {} // 특정 패키지 대상 포인트 컷
@Pointcut("anyPublicOperation() && inTrading()")
private void tradingOperation() {} // 위의 두 조건을 and(&&) 조건으로 결합한 포인트 컷
}
5)
Target Object
어떤 특정한 Advice가 적용될 대상을 말한다.
6)
AOP Proxy
AOP 기능은 특정한 메서드 호출 전 or 호출 후 에 덮어 씌워진다고 생각 할 수도 있지만,
실제로는 전 or 후 가 아니라 해당 클래스에 AOP를 바깥에 덧붙이는 방식 이다.
그 Target Object에 AOP를 덧붙이기 위한 작업을 AOP Proxy 라고 한다.
주로, CGLIB 라고 Code Generation Library 를 활용 하여,
실시간으로 코드를 생성 하고, 바로 프록싱 처리를 하게 된다.
7)
Weaving
Advice를 비즈니스 로직 코드에 삽입 하는것을 말한다.
AOP를 제대로 사용 하기 위해 꼭 필요한 라이브러리
>> AspectJ 라이브러리
기본적으로 제공되는 Spring AOP 로는 다양한 기법 (Pointcut 등) 을 사용 할 수 없다.
다양한 기법을 사용 할 수 있도록 AspectJ 라이브러리를 추가 하면 된다.
Reference
'Spring 프레임워크 > 이론' 카테고리의 다른 글
[ 스프링 프레임워크 ] Null Safety (2) | 2023.10.22 |
---|---|
[ 스프링 프레임워크 ] Validation / Data Binding (1) | 2023.10.20 |
[ 스프링 프레임워크 ] 핵심 기술 / 디자인 철학 (0) | 2023.10.18 |
Java / Spring Framework / SpringBoot (1) | 2023.10.18 |
@RequestMapping / @GetMapping / @PostMapping (0) | 2023.09.20 |