Spring/스프링 핵심 원리 - 고급편

[스프링 핵심 원리 - 고급편] @Aspect AOP

2023. 3. 7. 22:56
목차
  1. 1. @Aspect 프록시
본문은 인프런의 [스프링 핵심 원리 - 고급편]를 수강하고 정리한 글입니다. 필요에 따라 생략/수정된 부분이 있을 수 있으며, 내용이 추후 변경될 수 있습니다.
스프링 핵심 원리 - 고급편
1. 쓰레드 로컬
2. 템플릿 메서드 패턴과 콜백 패턴
3. 프록시 패턴과 데코레이터 패턴
4. 동적 프록시 기술
5. 스프링이 지원하는 프록시
6. 빈 후처리기
7. @Aspect AOP
8. 스프링 AOP 개념
9. 스프링 AOP 구현
10. 포인트컷
11. 실무 주의사항

 

전 챕터를 통해 자동으로 프록시를 적용하는 과정을 살펴봤다.

  1. 포인트컷과 어드바이스로 구성되어 있는 어드바이저를 만들어서 스프링 빈으로 등록
  2. 자동 프록시 생성기가 스프링 빈으로 등록된 어드바이저를 조회한다
  3. 포인트컷이 매칭되는 경우 프록시 적용

이제 직접 어드바이저를 생성하는 대신 @Aspect 프록시를 통해 애너테이션 기반의 프록시를 사용해보자.

 

 

1. @Aspect 프록시

1) @Aspect란?

스프링이 제공하는 @Aspect 애너테이션을 사용하면 편리하게 어드바이저를 생성할 수 있다

  • @Aspect는 관점 지향 프로그래밍(AOP)을 가능하게 하는 AspectJ 프로젝트에서 제공
  • 이것을 통해 프록시를 통한 AOP가 가능해짐

 

2) @Aspect 프록시 적용

LogTraceAspect

@Aspect // 애너테이션 기반 프록시를 적용할 때 필요
public class LogTraceAspect {

    // ...

    @Around("execution(* hello.proxy.app..*(..))") // 본 애너테이션은 포인트컷 역할, 메서드는 어드바이스 역할
    public Object execute(ProceedingJoinPoint joinPoint) throws Throwable {
        TraceStatus status = null;
        try {
            String message = joinPoint.getSignature().toShortString(); // 클래스명을 포함한 메서드의 시그니쳐를 리턴 후 String으로 변환
            status = logTrace.begin(message);

            //로직 호출
            Object result = joinPoint.proceed(); // target 호출, invocation.proceed()와 유사

            logTrace.end(status);
            return result;
        } catch (Exception e) {
            logTrace.exception(status, e);
            throw e;
        }
    }
}
  • @Aspect
    • 애너테이션 기반 프록시를 적용할 때 사용된다
    • 자동 프록시 생성기가 해당 애너테이션이 붙은 스프링 빈을 조회한다
  • @Around
    • 포인트컷 역할을 하며, 값에 Aspect 표현식이 들어간다
    • @Around의 메서드는 어드바이스가 된다
  • ProceedingJoinPoint joinPoint
    • 어드바이스에서 살펴본 MethodInvocation invocation과 유사한 기능
    • 내부에 실제 호출 대상, 인수 정보, 인스턴스 및 메서드 호출 정보가 포함되어 있다
  • 참고로 @Aspect 하나에서 메서드를 여러 개 선언함으로써 여러 어드바이저 생성할 수 있다

 

AopConfig

@Configuration
@Import({AppV1Config.class, AppV2Config.class})
public class AopConfig {

    @Bean
    public LogTraceAspect logTraceAspect(LogTrace logTrace) {
        return new LogTraceAspect(logTrace);
    }
}

 

3) @Aspect 프록시 설명

이렇게 간단하게 애너테이션 하나로 어드바이저 생성이 가능한 것은 자동 프록시 생성기 덕분이다.

 

자동 프록시 생성기(AnnotationAwareAspectJAutoProxyCreator)는 2가지 일을 한다.

  1. @Aspect를 보고 어드바이저로 변환해서 저장한다 (이러한 이유로 이름에 AnnotationAware가 붙었다)
  2. 어드바이저를 기반으로 프록시를 생성한다

 

4) @Aspect 어드바이저 생성 과정

1) 실행

  • 스프링 애플리케이션 로딩 시점에 자동 프록시 생성기를 호출한다

2) 모든 @Aspect 빈 조회

  • 자동 프록시 생성기가 @Aspect 애너테이션이 붙은 스프링 빈을 모두 조회한다

3) 어드바이저 생성

  • Aspect 어드바이저 빌더를 통해 @Aspect 애너테이션 정보를 기반으로 어드바이저를 생성한다

4) @Aspect 기반 어드바이저 저장

  • 생성한 어드바이저를 @Aspect 어드바이저 빌더 내부에 저장한다
    • @Aspect 어드바이저 빌더는 BeanFactoryAspectAdvisorsBuilder 클래스
    • @Aspect의 정보를 기반으로 어드바이저를 만들고, @Aspect 어드바이저 빌더 내부 저장소에 캐싱한다
    • 캐시에 어드바이저가 존재하는 경우 캐싱된 어드바이저를 반환한다

 

5) 어드바이저를 기반으로 프록시 생성

@Aspect 어드바이저 적용 후 자동 프록시 생성기의 작동 과정

1) 생성

  • 빈 대상이 되는 객체를 생성한다
  • 이때 대상은 @Bean과 @Component을 모두 포함한다

2) 전달

  • 생성된 객체가 빈 저장소에 등록되기 직전에 빈 후처리기에 전달된다

3-1) Advisor 빈 조회

  • 스프링의 빈 후처리기(자동 프록시 생성기)는 스프링 컨테이너에서 모든 Advisor를 조회한다

3-2) @Aspect Advisor 빈 조회

  • @Aspect 어드바이저 빌더 내부에 저장된 Advisor를 모두 조회한다

4) 프록시 적용 대상 체크

  • 조회한 Advisor에 포함된 포인트컷을 통해 프록시 적용 대상 여부를 판단한다
  • 메서드 하나라도 포인트컷 조건을 만족하면 프록시 적용 대상이 된다

5) 프록시 생성

  • 프록시 적용 대상이면 프록시를 생성하고 반환한다
  • 만약 적용 대상이 아니면 원본 객체를 반환한다

6) 빈 등록

  • 반환된 객체(프록시 or 원본)를 스프링 빈으로 등록한다

 

6) 정리

  • @Aspect를 사용하면 편리하게 애너테이션 기반 프록시를 적용할 수 있다
  • 지금껏 만들어온 애플리케이션 전반에 로그를 남기는 기능은 애플리케이션의 여러 기능들 사이에 걸쳐서 들어가는 관심사였다
    • 이를  횡단 관심사(cross-cutting)라고 한다
    • 다음 챕터부터는 횡단 관심사를 전문으로 해결하는 스프링 AOP에 대해 알아볼 것이다

저작자표시 비영리 (새창열림)

'Spring > 스프링 핵심 원리 - 고급편' 카테고리의 다른 글

[스프링 핵심 원리 - 고급편] 스프링 AOP 구현  (0) 2023.03.08
[스프링 핵심 원리 - 고급편] 스프링 AOP 개념  (0) 2023.03.08
[스프링 핵심 원리 - 고급편] 빈 후처리기  (0) 2023.03.06
[스프링 핵심 원리 - 고급편] 스프링이 지원하는 프록시  (0) 2023.03.06
[스프링 핵심 원리 - 고급편] 동적 프록시 기술  (0) 2023.02.21
  1. 1. @Aspect 프록시
'Spring/스프링 핵심 원리 - 고급편' 카테고리의 다른 글
  • [스프링 핵심 원리 - 고급편] 스프링 AOP 구현
  • [스프링 핵심 원리 - 고급편] 스프링 AOP 개념
  • [스프링 핵심 원리 - 고급편] 빈 후처리기
  • [스프링 핵심 원리 - 고급편] 스프링이 지원하는 프록시
코택
코택
코택
TaxFree
코택
전체
오늘
어제
  • 분류 전체보기 (369)
    • Spring (29)
      • Spring (18)
      • 스프링 핵심 원리 - 고급편 (11)
    • Spring Batch (4)
    • JPA (4)
    • CS (89)
      • 자료구조 (2)
      • 네트워크 (5)
      • 운영체제 (1)
      • 데이터베이스 (4)
      • SQL (7)
      • 알고리즘 이론 (4)
      • 알고리즘 문제 풀이 (66)
    • 웹 (28)
      • React.js (4)
      • Next.js (1)
      • Node.js (14)
      • FastAPI (4)
      • Django (5)
    • 프로그래밍 언어 (45)
      • Python (5)
      • Java + Kotlin (29)
      • JavaScript + TypeScript (11)
    • 테스트코드 (26)
      • ATDD, 클린 코드 with Spring (4)
      • 이규원의 현실 세상의 TDD: 안정감을 주는 코드.. (20)
    • 인프라 (6)
      • AWS (2)
      • Kubernetes (4)
    • 트러블슈팅 (25)
    • 책 (89)
      • Effective Java (54)
      • Effective Kotlin (14)
      • 도메인 주도 개발 시작하기: DDD 핵심 개념 정.. (11)
      • 웹 프로그래머를 위한 데이터베이스를 지탱하는 기술 (6)
      • 도메인 주도 설계 첫걸음 (4)
    • Git (10)
    • 회고 (5)
    • etc (8)

블로그 메뉴

  • 홈
  • 방명록
  • 관리
  • GitHub
  • LinkedIn

공지사항

  • 스킨 관련

인기 글

태그

  • http
  • 장고
  • Shortest Path
  • 그래프 탐색
  • fastapi
  • dp
  • atdd
  • 그래프
  • 깊이 우선 탐색
  • 브루트포스
  • mysql
  • 백준
  • 파이썬
  • BOJ
  • Git

최근 댓글

최근 글

hELLO · Designed By 정상우.
코택
[스프링 핵심 원리 - 고급편] @Aspect AOP
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.