이전에 정리한 AOP 글 참고하기
출처: https://steady-coding.tistory.com/608
AOP는 Aspect를 통해서 다양한 기능들을 분리해서 모듈화한다.
핵심 기능과 부가 기능을 분리하고, 분리된 부가 기능을 어디에 적용할지 선택한다.
OOP의 모듈화의 핵심 단위는 클래스이고, AOP의 모듈화의 핵심 단위는 관점(공통 관심)입니다.
AOP는 애플리케이션을 횡단 관심사 관점으로 보아, OOP의 부족한 부분을 보조하는 역할을 한다.
트랜잭션, 보안, 로깅 등은 핵심 기능은 아니지만, 애플리케이션에 필수적인 부가 기능이다.
그러므로 OOP만 사용하는 비즈니스 클래스에는 핵심 기능과 부가 기능이 함께 공존하게 되며 코드가 복잡해져서 파악이 어렵다.
또한, 공통적으로 사용되는 부가 기능의 중복 코드가 늘어나서, 유지보수가 어렵다.
부가 기능과 해당 부가 기능을 어디에 적용할지를 정의해서 모듈화한 것
Advice
+ PointCut
Advice
: 부가 기능을 정의한 코드
PointCut
: Advice를 어디에 적용할지 결정하는 것
여러 개의 Advice
+ PointCut
쌍으로 구성됨
Advice
+ PointCut
✅ 프록시 : 클라이언트와 서버 사이에 존재하며, 대리로 통신을 수행해주는 컴퓨터 시스템이나 응용 프로그램
[그림] 출처 : https://ko.wikipedia.org/wiki/%ED%94%84%EB%A1%9D%EC%8B%9C_%EC%84%9C%EB%B2%84
when
where
조인 포인트 실행
시점을 기준으로 한다.
1. Before
2. After
2-1. After returning
2-2. After throwing
2-3. After (finally)
3. Around
(ProceedingJoinPoint joinPoint)
를 사용해야 한다.@Around
만을 사용하는 것보다, 제약이 있지만 어떤 역할을 하는지 명확하게 알려줄 수 있는 @Before나 @After를 사용하는 것이 좋다.메서드 실행 지점, 생성자, 필드 값 변경, static 메서드 등이 있다.
AspectJ를 사용한 AOP는 AOP를 모든 지점에 다 적용할 수 있다.
하지만 프록시 방식을 사용하는 스프링 AOP는
메서드 실행 지점에만 AOP를 적용할 수 있다.
스프링 컨테이너가 관리할 수 있는 스프링 빈에만 AOP를 적용할 수 있다.
조인 포인트는 Advice 메서드의 인자로 들어간다.
실제 기능을 수행하는 객체 대신에 가상의 객체(프록시)를 사용해서 로직의 흐름을 제어하는 디자인 패턴
스프링 AOP는 프록시 패턴을 사용한다.
원래 Java가 동적 Proxy라서 jar 실행 파일로 돌아가면 필요한 Class를 가져오는데 Spring Container로 관리되면 Class 대신 Proxy 객체를 가져온다.
✔️ 프록시 객체를 쓰는 이유?
기존 코드의 변경없이 접근 제어 및 부가 기능을 추가하기 위해서
스프링은 런타임 시에 스프링 컨테이너가 빈을 만들기 때문에 런타임 시기에만 AOP가 가능하다.
Spring AOP는 스프링 컨테이너에 등록된 빈에서만 사용될 수 있다.
스프링 컨테이너는 Aspect의 적용 대상이 되는 객체를 생성하면서 자동으로 Proxy 객체를 같이 만든다.
✔️ 정리하자면!
스프링 컨테이너는 실행되기 전에 빈 객체를 만들면서, 해당 객체가 Aspect의 적용 대상인지 Pointcut을 통해 확인한다.
Aspect를 적용할 대상이면 프록시를 생성해주고 아니면 생성하지 않는다.
프록시 객체는 Aspect를 본인이 가로채서 객체 대신에 실행해준다.