AOP에 대해서 알아보자.
AOP는 Spring framework의 특징 중 하나이다.
그렇다면 왜 이렇게 AOP가 중요한지 알아보자.
AOP를 처음 보면 무슨 말인지 이해가 안될 것이다.
또한 왜 AOP와 나중에 배우게 될 Filter, Intercepter와 비교를 하는지 모를 것이다.
하지만 이 글을 보고 나면 AOP에 대해서 어느 정도 이해가 될 것이다.
AOP의 정의는 관점 지향 프로그래밍이다. 다시 말해 문제를 바라보는 관점을 기준으로 프로그래밍을 하는 방법이다.
그렇다면 관점을 기준으로 프로그래밍을 한다는 것이 무엇일까?
우리가 어떤 프로젝트를 코딩하다보면 분면 내가 만들고 있는 프로젝트의 주된 기능과 부가적인 기능이 있을 것이다.
여기서 주되 기능은 핵심 관심사항이고, 부가적인 기능은 공통관심 사항이라고 한다.
그렇다면 핵심 관심 사항과 공통 관심 사항은 무엇일까?
예를 들어서 우리가 스프링에서 회원을 검색하는 메서드를 구현했다고 생각해보자. 근데 우리는 회원 검색이 잘 동작하는지 메서드에 로깅을 넣어서 확인해 보고 싶다고 한다. 이때 로깅은 부가적인 기능이지 핵심 기능은 아니다.
그러면 보통은 검색 메서드 안에 로깅를 넣어서 검색 메서드가 실행이 되면 로깅도 동작하도록 할 것이다.
하지만 spring framework의 특징에서 POJO라는 특징을 지켜야 한다. POJO는 특정 프레임워크나 기술에 종속되지 않은 순수 자바 객체를 의미한다. 따라서 로깅같은 라이브러리를 사용하는 것은 지양하는 것이다. 또한 유지보수가 쉬워지도록 로깅과 검색 기능을 분리해 주는 것이 좋을 것이다.
이런 식으로 핵심기능에 반복되는 부가기능들을 분리 시켜주는 것이 AOP이다.
그렇다면 어떻게 분리해준다는 것인가??의문이 들 것이다.
분리해주는 방법을 알기 전에 몇가지 AOP기본 용어에 대해서 알아보고 넘어가자.
Target :
- 핵심기능을 담고 있는 모듈로 target은 부가기능을 부여할 대상이 됨.
Advice :
- 어느 시점(method의 수행 전/후,예외 발생 후 등..)에 어떤 공통 관심 기능(Aspect)을 적용할지 정의 한 것.
- Target에 제공할 부가기능을 담고 있는 모듈
JoinPoint :
- Aspect가 적용될 수 있는 지점.(method, field),
- 즉 target 객체가 구현한 인터페이스의 모든 method는 JoinPoint가 됨
PointCut :
- 공통 관심사항이 적용될 JoinPoint, Advice가 적용할 target의 method를 선별하는 정규 표현식,
- Pointcut표현식은 execution으로 시작하고 method의 Signature를 비교하는 방법을 주로 이용.
Aspect :
- 여러 객체에서 공통으로 적용되는 공통 관심 사항. (transaction,logging,security..),
- AOP의 기본 모듈,
- Aspect=Advice+ Pointcut ,
- Aspect는 Singleton형태의 객체로 존재
Weaving
- 어떤 Advice를 어떤 Pointcut(핵심사항)에 적용시킬 것인지에 대한 설정(Advisor)
- 즉 Pointcut에 의해서 결정된 타겟의 JoinPoint에 부가기능(Advice)을 삽입하는 과정을 뜻함
- Weaving은 AOP의 핵심기능(Target)의 코드에 영향을 주지 않으면서 필요한 부가기능(Advice)을 추가할 수 있도록 해 주는 핵심적인 처리과정
Aspect | @Aspect | “공통 관심사(Advice) + 대상 정의(Pointcut)” 를 묶어 놓은 모듈 | 클래스 단위 |
Pointcut | @Pointcut("표현식") | 어떤 JoinPoint(메서드 실행 시점 등)를 가로챌지 지정 | — |
Advice | @Before, @After, @AfterReturning, @AfterThrowing, @Around | 실제로 무엇을 할지 정의 | Pointcut과 결합해 실행 위치 결정 |
JoinPoint | (별도 애너테이션 X) | Advice 가 끼어들 수 있는 지점(메서드 호출, 필드 접근 등) | — |
위의 개념은 알아두면 이해하기 편할 것이다. 이해가 안된다면 다음 그림을 보면 이해가될 것이다.
1. AOP가 적용안된 코드(핵심관심 사항 + 공통관심 사항)
이미지를 보면 회원을 검색하는 핵심 로직과 메서드의 실행 시간을 측정해서 로깅하는 로직이 분리되어 있지 않고 합쳐져 있는 것을 볼 수 이다. 이렇게 되면 POJO의 특징이 지켜지지 않고, 유지보수가 힘들어지게 된다. 또한 실행 시간 측정 코드가 중복되면 가독성에도 떨어지게 된다.
2. AOP가 적용된 코드(핵심 관심사항(비즈니스 코드) 과 공통관심사항 분리)
위의 이미지는 @aspect Annotation을 이용하여 AOP를 구현한 모습이다.
우리가 주의 깊게 봐야할 부분들은 어피치가 달려있는 라인이다.
- @Aspect (①)
이 클래스를 “Aspect(공통 모듈)”로 등록해! 라는 표시입니다.
Spring 컨테이너가 읽어들여서 내부의 Pointcut·Advice 를 자동으로 연결해 줍니다. - @Pointcut (②)
- execution(public * com.example.demo.controller..*(..))
- 의미: controller 패키지 아래의 모든 public 메서드
- 이름(controllerLayer())만 지어 두면 여러 Advice 에서 재사용할 수 있어요.
- @Around (③)
- Pointcut(②)에 매칭된 메서드 “전/후” 전부를 감싸는 Advice.
- 내부에서 joinPoint.proceed()를 호출하면 원래 메서드가 실행됩니다.
- 실행 시간 측정, 트랜잭션, 캐싱처럼 전후 모두 필요한 로직에 적합합니다.
다른 Advice 들도 살펴보기
@Before | 대상 메서드 실행 직전 | 파라미터 검증, 권한 체크, 공통 로깅(시작) | @Before("controllerLayer()")<br>public void startLog() {…} |
@After | 대상 메서드 실행 직후 (성공·실패 무관) | 자원 정리, 공통 로깅(끝) | @After("controllerLayer()")<br>public void endLog() {…} |
@AfterReturning | 정상 종료 후 | 반환값 가공, 성공 로그 | @AfterReturning(pointcut="controllerLayer()", returning="ret") |
@AfterThrowing | 예외 발생 직후 | 예외 로깅, 롤백 트리거 | @AfterThrowing(pointcut="controllerLayer()", throwing="ex") |
방식장점단점
AOP 분리 | - 공통 로직 한 곳 집중 관리 - 핵심 클래스가 깔끔 |
- 초기 학습 곡선 - 표현식 관리 필요 |
혼합(try/finally) | - 별도 설정 없이 바로 구현 | - 중복 코드 다수 - 수정·테스트 시 모든 클래스 수정 |
여기까지 읽었다면 이제 AOP가 무엇이고, AOP는 어떻게 코드적으로 구현하는 것인지 감을 잡았을 것이다.
그렇다면 AOP는 어떤 식으로 동작하길래 AOP를 사용하고 관심사 분리가 되는 것일까 다음 글에서 알아보자.
'SpringBoot' 카테고리의 다른 글
Spring MVC (0) | 2025.04.30 |
---|---|
AOP(Aspect Oriented Programming) - (2) (0) | 2025.04.25 |
DI(Dependency Injection) - (3) (0) | 2025.04.18 |
DI(Dependency Injection) - (2) (0) | 2025.04.18 |
DI(Dependency Injection) - (1) (1) | 2025.04.18 |