
AOP 배경
소프트웨어를 개발하다 보면, 로깅이나 예외처리와 같은
비지니스로직이 아닌 코드를 반복하게 된다.
이러한 로직은 중요한 부분이지만, 실제 비지니스 로직과는 거리가 먼 것이 대부분이다.
여러 다른 부분의 코드에 사용될 수 있지만, 반복적이다.
유지보수를 할 때도, 여러곳에 분산되어 있으면 관리가 어렵게 된다.
이를 해결하기 위해 나온 개념이 Aspect Oriented Programming, 즉 관점지향 프로그래밍이다.
횡단관심사 (Cross-Cutting Concern)
여러 모듈에 걸쳐 공통적이고 반복적인 처리 로직을 일컷는 말이다.
AOP는 이러한 횡단관심사들을 한데 모아 관리하는 것에 관심이 있다.
횡단관심사의 대표적인 예들은 다음과 같다:
- 보안
- 로깅
- 트랜잭션
- 모니터링
- 캐시
- 예외
AOP의 주요 개념
애스펙트 (Aspect) | 횡단관심사가 되는 AOP의 단위이다. "로그출력", "예외처리" 등이 애스펙트의 예이다. |
조인 포인트 (Join Point) | 횡단관심사가 실행되는 시점이다. |
어드바이스 (Advice) | 조인포인트에서 실행되는 코드이고, 횡단관심사의 구현 코드이다. |
포인트컷 (Pointcut) | 조인포인트 중 어드바이스를 적용할 곳을 선택하는 표현식(expression)이다. 정규표현식과 비슷한 문법이 존재한다. |
위빙 (Weaving) | 애플리케이션 코드의 적절한 지점에 애스팩트를 적용하는 행위이다. 컴파일타임, 클래스로딩, 런타임 등의 시점이 존재한다. |
타깃 (Target) | AOP처리의 대상이 되는 객체, 즉 AOP처리에 의해 변화가 생길 객체이다. |
스프링에서 지원하는 어드바이스
스프링 AOP는 다음과 같은 어드바이스들을 제공한다.
Before | 조인포인트 이전에 실행 |
After Returning | 조인포인트의 종료 후 리턴시 실행 |
After Throwing | 조인포인트에서 예외 발생 시 실행 |
After | 조인포인트 완료 후 실행 |
Around | 조인포인트 전후에 실행 |
스프링 AOP
스프링 AOP는 가장 널리 쓰이는 AOP 프레임워크인 AspectJ를 내장하고 있다.
이는 애스펙트와 어드바이스를 정의하는 포인트컷 표현식과 위빙 기능을 제공한다.
gradle을 사용해 이를 사용가능하게 하려면 다음과 같이 설정하면 된다.
dependencies {
...
implementation 'org.springframework.spring-context'
implementation 'org.springframework.spring-aop'
implementation 'org.aspectj.aspectjweaver'
...
}
스프링 부트를 사용한다면, 다음 한줄만 추가하면 된다.
implementation 'org.springframework.boot:spring-boot-starter-aop'
메소드가 시작할때 로깅을 하는 Aspect는 다음과 같이 작성한다.
import org.aspectj.lang.JointPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class MethodLoggingAspect {
@Around("execution(* *.*..*ServiceImpl.*(..))")
public void logging(JointPoint jp){
log.debug("method started: " + joinPoint.getSignature().getName() + "()");
Object jp = joinPoint.proceed();
log.debug("method ended: " + joinPoint.getSignature().getName() + "()");
rerurn jp;
}
}
먼저 Aspect를 적용하기 위해서는 @Component를 사용해 Bean으로 등록해 주고, @Aspect를 적용해 준다.
@Around는 위에서 언급하였듯이 메소드가 실행되는 앞뒤에 작업을 수행해 줄 수 있다.
@Around안의 문자열은 AspectJ의 표현식이다. 이는 모든 패키지의 "ServiceImpl" 패턴이 들어가는 곳에서
메소드가 실행 되면 실행하는 Aspect라는 의미를 지닌다.
@Around는 원하는 시점에 따라 위에서 언급한 다섯가지를 상황에 맞게 사용하면 된다.
스프링부트가 아닌 스프링 프레임워크에서는 Config파일에 AOP를 활성화 해주어야 적용이 된다.
이는 AppConfig위에 @EnableAspectJAutoProxy를 달아주면 활성화가 된다.
포인트컷 표현식
AspectJ는 포인트컷 표현식을 사용해 조인포인트를 선택한다.
위 코드에 명시되어 있는 "execution(* *.*..*ServiceImpl.*(..))"이 이것의 예이다.
포인트컷의 기본 문법은 다음과 같다:

"*" 은 와일드카드를 의미하는데, 이는 임의의 문자열을 지정할 수 있다.
기본적으로 패키지 구조는 문자열과 "."을 사용해 표현한다.
".."를 사용하면 0개 이상의 여러 개층을 한번에 표현할 수 있게 된다.
또한 여러개의 표현식은 "||", "&&" 과 같은 논리 연산자로 조합할 수 있다.
스프링 제공 AOP 기능
스프링 프레임워크는 기본적으로 몇기자의 AOPfmf wprhdgksek.
@Transactional | 복잡한 트랜잭션을 관리하고, 처리하는 Commit, 실패시의 Excpetion처리, 그리고 실패시 Rollback까지 수행한다. |
@PreAutorize | 스프링 시큐리티의 Authorization을 수행한다. 특정 메소드가 특정 사용자의 권한으로 제공 가능한지를 판별할 수 있다. |
@Cacheable | 간단한 기능의 캐싱을 제공한다. 인자로 키를 제공하면 수행 결과를 캐시한다. |
@Async | 메서드의 비동기 처리를 제공한다. |
@Retryable | 웹 기능을 하는 메서드가 실패했을 때 재시도 하는 로직을 수행한다. maxAttempts 인자를 통해 최대 N번까지의 재시도를 반복하게 할 수 있다. |
참고자료
스프링 철저 입문, 위키북스
'서버 개발 > 스프링' 카테고리의 다른 글
[스프링 클라우드] 서비스 디스커버리 (0) | 2024.10.03 |
---|---|
스프링 프레임워크 - (4) 데이터 바인딩 (0) | 2019.09.10 |
스프링 프레임워크 - (2) 스프링 빈 (Bean) (0) | 2019.09.02 |
스프링 프레임워크 - (1) 의존성 주입 (DI) (0) | 2019.09.02 |