본문 바로가기
Spring|Spring-boot/Spring AOP

Spring AOP

by oncerun 2022. 1. 27.
반응형

사전 지식

  • 빈 후처리기
  • @Aspect

Aspect 기억 되살리기

 

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

 

1. 스프링 애플리케이션 로딩 시점에 자동 프락시 생성기(AnnotationAwareAspectJAutoProxyCreator)

호출

 

2. 자동 프록시 생성기는 스프링 컨테이너에서 @Aspect 애노테이션이 붙은 스프링 빈 모두 조회

 

3. @Aspect Advisor Builder를 통해 어드바이저 생성

 

4. 생성한 어드바이저를 빌더 내부에 저장.

 

 

자동 프록시 생성기 작동 과정

 

1. 스프링 빈 대상 객체 생성

2. 컨테이너에 저장하기 전 빈 후처리기 전달

3. 스프링 컨테이너에서 Advisor 빈, @Aspect 어드바이저 빌드에 저장된 Advisor빈 모두 조회

4. 프록시 적용 대상을 포인트 컷으로 판단, 클래스, 메서드 등등.. 하나라도 만족 시 프록시 적용돼 상.

5. 프락시 생성

6. 빈 등록

 

 

 

* 기억해야 할 것

 

포인트 컷은 두 가지의 역할을 한다. 

 

1. 프락시 객체의 대상인지 아닌지 판단.

2. 메서드 실행 대상 여부 판단.

 

 

 

AOP

 

 - 핵심기능과 부가 기능을 분리하는 문제점을 해결하기 위한 방법.

 - 부가 기능을 한 곳에서 관리하여 변경 지점을 최소화

 - 해당 부가기능을 어디에 적용할지 선택하는 기능

 - 부가기능 + 어디에 적용할지를 합쳐서 하나의 모듈로 만든 것이 AOP이다.

 

 

 

AspectJ 프레임워크

 

-  AOP의 대표적인 구현으로 AspectJ가 있다. 스프링도 AOP를 지원하지만 대부분 AspectJ문법을 차용하고, AspectJ의 일부 기능만을 제공한다.

이 말은 횡단 관심사를 처리할 때 스프링이 제공하는 AOP만으로도 가능할지 아니면 좀 더 기능이 많은 AspectJ를 사용할지 선택하여야 한다.

 

 

AOP 적용 방식

 

  • 컴파일 시점
  • 클래스 로딩 시점
  • 런타임 시점(프록시도입)

 

컴파일 시점(AspectJ 직접 사용)

 

 . java 소스 코드를 컴파일러를 사용해서. class를 만드는 시점에 부가 기능 로직을 추가할 수 있다. 이 경우에는 AspectJ가 제공하는 특별한 컴파일러는 사용해야 한다.  AspectJ 컴파일러는 Aspect를 확인해서 해당 클래스가 적용 대상인지 확인하고, 적용 대상인 경우 부가 기능 로직을 적용한다. 

이렇게 원본 로직에 부가 기능 로직이 추가되는 것을 위빙(Weaving)이라 한다.

하지만 특별한 컴파일러가 필요하고 복잡하다. 

 

클래스 로딩 시점(AspectJ 직접 사용)

 

자바는. class 파일을 JVM 내부의 클래스 로더에 보관한다.  이 상황에서. class 파일을 조작한 다음 JVM에 올릴 수 있다. 자바는. class를 JVM에 저장하기 전에 조작하는 기능을 제공한다.

https://docs.oracle.com/javase/6/docs/api/java/lang/instrument/package-summary.html

 

java.lang.instrument (Java Platform SE 6)

The manifest of the agent JAR must contain the attribute Agent-Class. The value of this attribute is the name of the agent class.

docs.oracle.com

여러 모니터링 툴들이 이 방식을 차용했으며, 이 시점에 Aspect를 적용하는 것을 로드 타임 위빙이라고 한다.

하지만 자바 실행 시 특별한 옵션인 java -javaagent를 통해 클래스 로더 조작기를 지정해야 한다.

 

 

 

런타임 시점

 

컴파일도 마무리되고, 클래스 로더에 클래스도 전부 올라가서 자바가 실행되고 난 다음을 런타임이라고 한다. 즉 자바의 첫 진입점인 main() 메서드가 실행된 다음이다.

 

여기서부터는 자바 언어가 제공하는 범위 안에서 부가 기능을 제공해야 하기 때문에 스프링 컨테이너의 도움을 받아 프록시, DI, Bean postprocessor와 같은 개념을 사용한다.  보통 이 방식을 많이 사용한다.

하지만 단점이 존재한다. 프록시를 사용하기 때문에 AOP기능에 제약이 존재한다.  프록시 방식에는 메서드 오버 라이딩, 즉 다형성을 통해 동작하기 때문에 생성자, static 메서드, 필드 값에는 적용될 수 없다.

 

까먹지 말자 프록시를 사용하는 스프링 AOP의 조인 포인트(적용 지점)는 메서드 실행으로 제한될 수밖에 없다.

또한 프록시 등록 과정을 생각해보면 스프링 빈에만 AOP를 적용할 수 있다는 점도 기억하자.

 

 

* AspectJ를 사용하고 싶다면 당신은 Aspect 컴파일러를 적용하여 운영하는 애플리케이션을 관리해야 하며,  AspectJ 전용 문법을 숙지해야 하고, 자바 실행 옵션을 일일이 지정해야 한다. 

 

* 단어를 강조하는 이유는 커뮤니케이션을 원활히 하기 위해서...

 

 

 

AOP 용어

 

 조인 포인트(Join point)

  • AOP를 적용할 수 있는 모든 지점, 어드바이스가 적용될 수 있는 위치
  • 단 스프링 AOP는 런타임 시점에 프록시로 동작하기 때문에 항상 메서드 실행 지점으로 제한

 

포인트컷 (Pointcut)

  • 조인 포인트 중에서 어드바이스가 적용될 위치를 선별하는 기능

타겟(Target)

  • 어드바이스를 받는 객체

어드바이스 (Advice)

  • 부가기능
  • Around, Before, After.. 다양한 어드바이스가 존재.

애스펙트(Aspect)

  • Advice + Pointcut을 모듈화
  • @Aspect

위빙(Weaving)

  • 포인트 컷으로 결정한 타겟의 조인 포인트에 어드바이스를 적용하는 것

AOP 프록시

  • AOP 기능을 구현하기 위한 프록시 객체로 스프링에서는 인터페이스가 있는 경우 JDK Dynamic Proxy를 없는 경우 CGLIB 프록시를 구별하여 적용한다.(옵션으로 고정 가능)

 

 

반응형

'Spring|Spring-boot > Spring AOP' 카테고리의 다른 글

Pointcut - within, args  (0) 2022.01.29
Pointcut - execution  (0) 2022.01.29
Spring AOP (2)  (0) 2022.01.29
[Spring boot] AOP 활용예제  (0) 2021.06.09
[Spring] AOP(Aspect Oriented Programming) 방법론  (0) 2020.06.22

댓글