김영한의 스프링 핵심 원리(고급편) - @Aspect, AOP

2025. 2. 24. 22:40·김영한의 스프링 핵심 원리 - 고급편

Question

  • 자동 프록시 생성기와 @Aspect의 관계를 설명하시오
  • 어드바이저 기반으로 프록시를 생성하는 모든 과정을 설명하시오
  • AOP란?
  • AOP를 적용하는 3가지 방식에 대해 설명하시오
  • 스프링 AOP의 Joint Point는?

 

@Aspect

  • 스프링에서 자동 프록시 생성기( AnnotationAwareAspectJAutoProxyCreator )는 Advisor 를 자동으로 찾아와서 필요한 곳에 프록시를 생성하고 적용해줌
  • 자동 프록시 생성기는 @Aspect을 찾아 이것을 Advisor로 만들어주는 역할도 해줌
  • @Aspect를 보고 어드바이저로 변환해 저장해주는데, 따라서 @Aspect에는 포인트컷과 어드바이스가 있음

 

@Aspect을 어드바이저로 변환해 저장하는 과정

  • 실행: 스프링 애플리케이션 로딩 시점에 자동 프록시 생성기를 호출
  • 모든 @Aspect 빈 조회: 자동 프록시 생성기는 스프링 컨테이너에서 @Aspect 애노테이션이 붙은 스프링 빈
    을 모두 조회
  • 어드바이저 생성: @Aspect 어드바이저 빌더를 통해 @Aspect 애노테이션 정보를 기반으로 어드바이저를
    생성
  • @Aspect 기반 어드바이저 저장: 생성한 어드바이저를 @Aspect 어드바이저 빌더 내부에 저장한다.

 

@Aspect 어드바이저 빌더

  • @Aspect 정보 기반으로 포인트컷, 어드바이스, 어드바이저를 생성 및 보관
  • 어드바이저 빌더 내부에 해당 정보를 저장하고 조회시 이미 있는 경우에는 캐시 기능도 제공

 

어드바이저를 기반으로 프록시 생성과정

  • 생성: 스프링 빈 대상이 되는 객체를 생성한다. ( @Bean , 컴포넌트 스캔 모두 포함)
  • 전달: 생성된 객체를 빈 저장소에 등록하기 직전에 빈 후처리기에 전달한다.
  • Advisor 빈 조회: 스프링 컨테이너에서 Advisor 빈을 모두 조회한다.
  • @Aspect Advisor 조회: @Aspect 어드바이저 빌더 내부에 저장된 Advisor 를 모두 조회한다.
  • 프록시 적용 대상 체크: 앞서 3-1, 3-2에서 조회한 Advisor 에 포함되어 있는 포인트컷을 사용해서 해당 객체가 프록시를 적용할 대상인지 아닌지 판단. 이때 객체의 클래스 정보는 물론이고, 해당 객체의 모든 메서드를 포인트컷에 하나하나 모두 매칭해보고 조건이 하나라도 만족하면 프록시 적용 대상이 됨. 예를 들어서 메서드 하나만 포인트컷 조건에 만족해도 프록시 적용 대상이 된다.
  • 프록시 생성: 프록시 적용 대상이면 프록시를 생성하고 프록시를 반환한다. 그래서 프록시를 스프링 빈으로 등록. 만약 프록시 적용 대상이 아니라면 원본 객체를 반환해서 원본 객체를 스프링 빈으로 등록.
  • 빈 등록: 반환된 객체는 스프링 빈으로 등록

 

AOP(Aspect-Oriented-Programming)

  • 애플리케이션을 바라보는 관점을 하나하나의 기능에서 횡단 관심사 관점으로 달리 보는 것
  • 핵심 기능과 부가 기능을 분리하고, 부가 기능을 어디에 적용할지 선택하는 기능을 합해 하나의 모듈로 만든 것이 애스펙트
  • 부가 기능은 일반적으로 여러 곳에서 반복적으로 사용되며 그 중에 하나가 로그 출력 기능
  • AOP는 OOP를 대체하는 것이 아니라 횡단 관심사 처리에 어려운 OOP의 부족한 부분을 보완하는 목적

 

 

AOP 적용 방식

  • 컴파일 시점
    • .java 소스를 컴파일러를 사용해 .class로 만드는 시점에 부가 기능 로직을 핵심 기능 로직에 실제로 넣어서 컴파일
    • 이렇게 원본 로직에 부가 로직이 추가되는 것을 위빙(Weaving: 옷감을 짜는 것)이라 함
    • 컴파일 시점에 부가기능을 적용하려면 특별한 컴파일러도 필요하고 복잡하다는 단점이 있음
  • 클래스 로딩 시점
    • 자바를 실행하면 .class 파일을 JVM 내부의 클래스 로더에 보관하는데, 이 때 .class 파일을 조작해 JVM에 올림
    • 로드 타임 위빙 방식
    • 자바를 실행할 때 특별한 옵션(java -javaagent)로 클래스 로더 조작기를 지정해야하는데, 이 부분이 번거럽고 운영이 어려움
  • 런타임 시점
    • 이미 컴파일도 끝나고, 클래스 로더에 클래스도 다 올라가 자바가 실행되고 난 이후의 시점
    • 프록시를 사용해 빈을 프록시 빈으로 바꿔치기 하는 방식
    • 프록시를 사용하므로 AOP 기능에 일부 제약이 있지만 복잡한 설정이 따로 필요 없고 스프링만 있으면 됨

 

AspectJ

  • AOP의 대표적인 구현으로 AspectJ 프레임 워크가 있음
  • AspectJ는 위 AOP 적용 방식 중 컴파일 시점과 클래스 로딩 시점 방식을 지원 함
  • 스프링은 AspectJ의 문법을 차용하고 프록시 방식의 AOP를 적용하는데, 실제로 AspectJ를 직접 사용하는 것은 아님
  • AspectJ가 더 많은 기능을 지원하지만 사용이 복잡하다는 단점과 AOP를 통해 대부분의 문제를 해결할 수 있기에 AspectJ를 직접 사용할 일은 거의 없음

 

AOP의 적용 위치

  • 적용 가능 지점(Joint Point): 생성자, 필드 값 접근, static 메서드 접근, 메서드 실행
  • AspectJ는 바이트 코드를 실제로 조작 가능하므로 위 모든 지점에 AOP를 적용 가능
  • 프록시 방식을 사용하는 스프링 AOP는 메서드 실행 지점에만 AOP를 적용 가능
  • 프록시 방식 AOP는 메서드 오버라이딩 방식으로 동작하므로 당연히 메서드 실행 시점만 적용 가능
  • 프록시 방식 AOP는 스프링 컨테이너가 관리하는 스프링 빈에만 AOP를 적용 가능(new 같은 것으로 생성한 객체는 불가)

'김영한의 스프링 핵심 원리 - 고급편' 카테고리의 다른 글

김영한의 스프링 핵심 원리(고급편) - 포인트컷 지시자(execution 등)  (1) 2025.02.25
김영한의 스프링 핵심 원리(고급편) - AOP의 포인트컷, AOP의 어드바이스 종류  (0) 2025.02.25
김영한의 스프링 핵심 원리(고급편) - 빈 후처리기  (0) 2025.02.22
김영한의 스프링 핵심 원리(고급편) - 프록시 팩토리  (0) 2025.02.22
김영한의 스프링 핵심 원리(고급편) - 동적 프록시 기술  (0) 2025.02.21
'김영한의 스프링 핵심 원리 - 고급편' 카테고리의 다른 글
  • 김영한의 스프링 핵심 원리(고급편) - 포인트컷 지시자(execution 등)
  • 김영한의 스프링 핵심 원리(고급편) - AOP의 포인트컷, AOP의 어드바이스 종류
  • 김영한의 스프링 핵심 원리(고급편) - 빈 후처리기
  • 김영한의 스프링 핵심 원리(고급편) - 프록시 팩토리
5jyan5
5jyan5
  • 5jyan5
    jyan
    5jyan5
  • 전체
    오늘
    어제
    • 분류 전체보기 (242)
      • 김영한의 스프링 핵심 원리(기본편) (8)
      • 김영한의 스프링 핵심 원리 - 고급편 (11)
      • 김영한의 스프링 MVC 1편 (1)
      • 김영한의 스프링 DB 1편 (3)
      • 김영한의 스프링 MVC 2편 (3)
      • 김영한의 ORM 표준 JPA 프로그래밍(기본편) (9)
      • 김영한의 스프링 부트와 JPA 활용2 (2)
      • 김영한의 실전 자바 - 중급 1편 (1)
      • 김영한의 실전 자바 - 고급 1편 (9)
      • 김영한의 실전 자바 - 고급 2편 (9)
      • Readable Code: 읽기 좋은 코드를 작성.. (2)
      • 김영한의 실전 자바 - 고급 3편 (9)
      • CKA (118)
      • 개발 (37)
      • 경제 (4)
      • 리뷰 (1)
      • 정보 (2)
  • 블로그 메뉴

    • 링크

    • 공지사항

    • 인기 글

    • 태그

      @discriminatorcolumn
      김영한
      단방향 맵핑
      reentarantlock
      페치 조인
      @discriminatorvalue
      gesingleresult
      typequery
      조회 성능 최적화
      자바
      @within
      Thread
      프록시
      jdk 동적 프록시
      락
      JPQL
      고급
      프록시 팩토리
      hibernate5module
      버퍼
      log trace
      WAS
      Target
      requset scope
      cglib
      빈 후처리기
      스레드
      jpq
      양방향 맵핑
      @args
    • 최근 댓글

    • 최근 글

    • hELLO· Designed By정상우.v4.10.2
    5jyan5
    김영한의 스프링 핵심 원리(고급편) - @Aspect, AOP
    상단으로

    티스토리툴바