이 글은 우테코(봄의 AOP와 Spring AOP) 및 여러 정보들을 종합해 학습한 내용입니다.
- https://www.youtube.com/watch?v=hjDSKhyYK14&list=WL&index=84&t=305s
- https://engkimbs.tistory.com/746
- https://yadon079.github.io/2021/spring/spring-aop-core
What is 스프링 AOP?
AOP는 Aspect Oriented Programming의 약어 (관점 지향 프로그래밍)
이 관점 지향은 "관점"을 이용해 로직을 관점의 측면에서 나누어서 본다(핵심vs부가적). 그래서 이 관점을 기준으로 각각을 모듈화 하겠다는 것이다.
그럼 이 모듈을 필요로 하는 곳에서 호출만 하면 되니 어떻게보면 Java의 핵심인 객체 지향스러움 이라고 생각할 수 있다.
그래서 개발자의 입장에서 반복 작업을 줄이고 핵심 기능 개발에만 집중이 가능해 생산성도 자연스레 올라간다.
이 AOP는 핵심 기능에 공통 기능을 삽입하는 것이며, 핵심 기능의 코드를 수정하지 않으면서 공통 기능의 구현을 추가한 것이다. 이것이 바로 AOP가 추구하는 방향성이자 목적이다.
위의 그림에서 보면 각 색뱔로 반복해서 사용하는 부분이 있음을 확인할 수 있다.
이런 모듈을 흩어진 관심사(Crosscutting Concerns)라고 한다. 흩어진 관심사들을 Aspect로 모듈화 하고, 핵심적인 비즈니스 로직에서 분리해 재사용 하겠다는 것이 AOP의 지향점이다.
AOP에서 사용되는 용어?
- Target Object : 부가 기능을 부여할 대상
- Aspect : AOP의 기본 모듈로 흩어진 관심사(Crosscutting Concerns)를 결합해 모듈화 한 것으로 Advide와 Point Cut이 포함
- Advice : 타깃에게 제공할 부가 기능을 담은 모듈, Aspect가 하고자 하는 동작과 시간을 정의하고 있음.
- JoinPoint : 프로그램의 실행 내부에서 Advice가 적용될 수 있는 위치
- PointCut : Advice에 적용할 JoinPoint를 선발하는 작업 or 그 기능을 정의한 모듈
예를 들어 어떠한 프로그램의 실행 흐름(Program Executin)이 있다고 가정해보자
이 실행 흐름 내부엔 각 각 부가기능인 Advice가 적용될 위치인 Join Point가 존재한다.
AOP의 기본 모듈인 Aspect가 있으며, 이 Aspect는 Advice와 PointCut로 구성되어 있다.
public interface Calculator{
long Plus(long n, long a);
long Minus(long n, long a);
}
이 계산기 인터페이스에는 2개의 메서드(Plus, Minus)가 존재하는데, 이 메서드들은 부가기능을 적용 할 수 있는 지점들인 Join point라 할 수 있고, 또 다른 기능인 뭐 데이터 log를 찍는 기능이 있다라고 하면, 이 log 찍는 기능은 Advice, 즉 부가기능이고, 이 부가기능을 어디에 적용할지는 PointCut이라고 한다.
이 Advice와 PointCut을 합친 것을 Aspect라 한다.
AOP를 구현하는 방법 (직접 블로그 찾아가면서 해보는 방법이 가장 빠를 것으로 생각함.)
- 컴파일 시점에 코드에 공통 기능 삽입
- 클래스 로딩 시점에 바이트 코드에 공통 기능 삽입
- 런타임 시점에 프록시 객체를 생성하여 공통 기능 삽입
1. 컴파일 시점에 코드에 공통 기능 삽입 (AspectJ)
= 컴파일 시점(.java 파일을 .class 파일로 만들 때)에 바이트 코드를 조작하여 조작된(AOP가 적용된) 바이트코드를 생성
2. 클래스 로딩 시점에 바이트 코드에 공통 기능 삽입 (AspectJ)
= 순수하게 컴파일한 뒤, 클래스를 로딩하는 시점에 클래스 정보를 변경(Load Time Weaving, 로드타임 위빙)
1번과 2번 같은 경우는 AOP 프레임워크에서 제공하는 AspectJ 컴파일러나 클래스 로더 조작기 같은 것을 사용해야해서 조금 유연한 AOP를 사용할 수 있지만 추가적인 의존성을 적용해야하는 단점이 있다.
3. 런타임 시점에 프록시 객체를 생성하여 공통 기능 삽입 (Spring AOP)
= 스프링 AOP가 사용하는 방법. A 클래스 타입의 Bean을 만들 때 A 타입의 Proxy Bean2을 만들어 Proxy Bean이 Aspect 코드를 추가하여 동작.
그래서 앞서 설명한 컴파일 시점이나 클래스 로딩 시점에서 사용하는 컴파일러나 클래스 로더 조작기를 설정하지 않아도 되며, 프록시는 메서드 오버라이딩 개념으로 동작하기 때문에, 스프링 AOP에서는 메서드 실행 시점에서만 AOP를 적용할 수 있다. 또 스프링 컨테이너가 관리할 수 있는 빈에만 AOP를 적용할 수 있다. AspectJ를 직접 사용하는 것이 아니라 AspectJ의 문법을 차용하고 프록시 방식의 AOP를 적용한다.
스프링에서는 다양한 방식으로 AOP를 지원한다.
- IoC/DI 컨테이너
- Dynamic Proxy
- Decorator Pattern/Proxy Pattern
- 자동 프록시 생성 기법
- 빈 오브젝트의 후처리 조작 기법
Spring에서는 빈으로 등록된 대상만 AOP를 사용할 수있다. (@Component)
그 후 사용하고자 하는 클래스에 @Aspect를 정의해줘야 한다.
그리고 @PointCut와 @Around를 정의해줘야 한다.
'스프링' 카테고리의 다른 글
[#1] Spring Security - 시큐리티는 무엇이고, Filter는 무엇인지 (0) | 2022.12.29 |
---|---|
[10분 테코톡] - @JDK Dynamic Proxy & CGLIB (0) | 2022.12.22 |
[10분 테코톡] - @Transactional (0) | 2022.12.21 |
Spring- Lombok의 이해와 @Annotation (계속 추가합니다.) (0) | 2022.12.14 |
Controller, Service 왜 나눌까요? (2022.12.02 - 작성 중) (0) | 2022.12.02 |