AOP 가 무엇인지 알아보기에 앞서 AOP 가 등장하게된 배경에 대해 먼저 알아보자.
웹 어플리케이션 서버에서 흔히 사용되는 패턴인 MVC + Repository 패턴이다. 각 역할별 책임을 분담하여 레이어를 이루는 구조이다. 만약 위 구조에서 각 레이어에서 호출, 응답에 대해 로그를 남겨 추적하고 싶다면 어떻게 해야할까?
(일반적으론 이런 경우 APM 이 사용되지만 배경 설명을 위해 로그를 예로 들었다.)
단순한 방법으론 위와 같이 각 레이어에 로그 추적 코드를 추가하는 방법이 있을것이다. 하지만 만약 로그 추적을 해야하는 파일의 갯수가 수백개인 경우에도 이렇게 작업을 해야할까? 할수야 있겠지만 매우 비효율적이고 관리하기 힘든 형태이다.
잘 살펴보면 로그 추적 로직은 공통 코드로서 유틸리티한 기능이기 때문에 유틸리티 클래스로 빼서 사용할순 있지만 매번 호출을 해야한다는 문제점이 남아있다. 이런 공통 기능을 매번 호출 할 필요없이 한곳에서 관리할순 없을까? 이러한 고민으로부터 시작하여 등장한게 AOP (Aspect Oriented Programming) 관점 지향 프로그래밍 이다. 사실 관점 지향 이라는 말이 한번에 와닿진않는데 이를 설명해보자면 Controller, Service, Repository 같이 기능과 책임을 나누어 보지않고 다른 관점으로 바라보는 것이다.
로그 추적 로직은 사실 핵심 로직은 아니고 부가적으로 추가된 기능일 뿐이기 때문에 아래와 같이 바라볼수 있다. 핵심 로직인 Controller, Service, Repository 가 실행되기 이전, 이후에 호출되는 부가 로직일 뿐이다.
그래서 Controller, Service, Repository 를 각각 별개의 레이어로 보지않고 동일 선상에 놓고 보는것이고 이걸 횡단 관심사 관점(cross-cutting concerns)으로 본다고 한다.
AspectJ 프레임워크가 AOP 구현에 대해선 대표적이다. AOP 를 구현하는 방법엔 3가지가 있는데 컴파일 시점, 클래스 로딩 시점, 런타임 시점이 있다. 컴파일 시점은 특별한 컴파일러를 사용하여 컴파일시 .java -> .class 를 만드는 시점에 코드를 추가 하는것이다. 클래스 로딩 시점은 .class 를 JVM 에 저장하기전에 조작하는 방법으로 APM 에이전트들이 이러한 방식을 주로 사용한다고 한다.
이 글에선 스프링부트에 적용되는 AOP 에 대해서만 알아보겠다.
스프링부트 AOP 구현 방식
- AspectJ 문법 차용
- AspectJ 의 일부기능만 제공
- 프록시 사용
프록시 자동생성기 라이브러리를 사용하자.
build.gradle
implementation 'org.springframework.boot:spring-boot-starter-aop'
위 라이브러리를 사용하면 Pointcut, Adivce 로 이루어진 Advisor 를 스프링 빈에 등록해준다.
Advisor 의 작동 방식은 Pointcut 으로 프록시를 적용할 빈의 조건을 명시해주고 조건에 부합할시 Advice 를 적용하는 형태이다.
@Aspect 어노테이션 사용시 스프링이 프록시를 생성 할수있다.
스프링 부팅 시점에 어드바이저 빌더에 Advisor 들이 생성되어 저장된다. 그 이후 밑의 자동 프록시 생성되는 과정에서 Advisor 를 조회하여 스프링 컨테이너에 프록시를 등록한다.
- 런타임 시점에 적용
다음 글에선 스프링부트 AOP 적용 방법에 대해서 알아보자.
참고자료
- https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B3%A0%EA%B8%89%ED%8E%B8/dashboard
'IT > 스프링' 카테고리의 다른 글
[Spring] 스프링부트 AOP 구현 및 예제 (0) | 2023.10.20 |
---|---|
[spring] 스프링부트 어노테이션 @Bean, @Component 차이 (1) | 2023.10.02 |
[java] JPA (Java Persistence API) 란? (0) | 2023.02.06 |