Spring Boot

Spring AOP / AOP에 대하여

OneMoreThing 2024. 3. 12. 19:20

1. AOP 란 무엇일까?

AOP는 Aspect Oriented Programming 을 줄인 말로, 관점 지향 프로그래밍이라 불린다.

2. AOP가 필요한 이유

프로젝트를 구현하다 보면 핵심적인 비지니스 로직 외에 부가적인 기능들을 추가해야하는 상황이 생긴다. 예를 들면, 메소드를 호출할 때마다 로그를 남긴다거나, 성능을 테스트하기 위해 메소드가 실행되는 시간을 측정하는 등 다양한 상황이 발생한다. 이런 부가기능들을 핵심 비지니스 로직에 포함할 수도 있지만, 이 경우 다양한 문제가 발생하게 된다.

 

  1. 핵심 로직 외에 부가기능이 포함되어 코드를 파악하기 어려워진다.

부가기능이 1가지만 있다면 크게 상관이 없겟지만, 부가기능이 많아질 수록 핵심기능보다 부가기능의 코드가 더 많아지는 상황이 발생하게 된다.

  2. 부가기능에 의해 반복되는 코드가 발생한다.

부가기능은 특정한 메소드에만 적용되는 것 보다 프로그램 전반적으로 적용되는 경우가 빈번하다. 수행시간이나 로그를 남기는 것을 생각하면 이해하기 쉽다. 모든 메소드마다 일일히 추가하는 것을 생각하면 벌써 손이 저려온다.

  3. 유지보수가 힘들다.

반복 노가다를 통해 추가한 부가기능을 수정해야하는 상황을 상상해보자. 처음 부가기능을 추가했던 것 이상의 노력이 필요할 것이다. 또한 실수로 특정 부분은 수정을 거치지 않았다면, 부가기능의 신뢰성이 떨어지게 된다.

 

위의 문제들을 고려했을 때, 부가기능을 핵심기능에서 따로 분리해내서 관리하면 좋겠다는 생각이 든다. 이를 위한 것이 AOP, 관점 지향 프로그래밍이다.

 

<부가기능의 종류>

본격적인 AOP에 대한 내용으로 들어가기 전에 AOP라는 프로그래밍 패러다임이 생길 정도로 추가될 수 있는 부가기능이 다양한 지에 대해 의문이 생긴다. AOP로 관리할 수 있는 부가기능에는 어떤 것들이 있을까? 대표적인 부가기능들을 리스트로 정리해보았다.

  1. 로깅(Logging) : 메소드의 시작과 종료를 기록
  2. 예외처리 : 비지니스 로직에서 발생하는 예외를 GlobalExceptionHandler로 처리
  3. 퍼포먼스 모니터링 : 특정 기능의 실행시간을 측정
  4. 토큰 체크 : 특정 비지니스 로직을 수행할 수 있는 권한이 있는지 확인
  5. 데이터베이스 연결(JDBC), 파일 입출력, 캐싱, 사용자 행위 감시(Audit), etc..

어플리케이션의 규모가 커질수록 더 많은 부가기능이 생길 수 있다. 위의 기능들을 핵심 로직에 끼워넣게 되면 발생할 상황들은 상상하고 싶지 않다.

 

3. Spring AOP의 특징

Spring AOP는 프록시 패턴 기반으로 AOP를 구현하였다. 스프링이 프록시(가짜 혹은 대리) 객체를 중간에 삽입한다. DispatcherServlet 과 Controller 입장에서는 아무런 변화도 체감되지 않는다.

출처 : 스파르타 코딩클럽, Spring Master 5주차 강의자료

 

4. AOP 의 주요 용어

AOP에서 사용되는 새로운 용어들이 있다.

  1. Target : 핵심 기능을 담고 있는 모듈을 의미한다. 부가기능(Aspect)이 적용될 곳이다. 클래스나 메소드가 해당된다.

  2. JoinPoint : 클라이언트가 호출하는 모든 비지니스 메소드이다. PointCut의 후보들이 모여있는 집합이다.

  3. PointCut : 특정한 조건에 의해 필터링된 JoinPoint 이다. 

    - Advice가 적용될 타겟을 선별하기 위해 정규표현식을 활용한다.

    - 포인트컷 표현식 : execution으로 시작하고 method signature(return type, method name, parameter)를 비교하는 방법을 주로 이용한다.

  4. Advice : 타겟에 적용할 부가기능을 담은 구현체

  5. Aspect : PointCut 과 Advice 의 결합

    - Bean 클래스 위에 붙인다. -> @Component 가 붙은 클래스 위에 @Aspect 붙임

    - 어떤 포인트컷 메소드에, 어떤 어드바이스 메소드를 실행할지 결정함

 

글로 읽으면 이해가 어렵기 때문에 그림으로 표현하면 다음과 같다.

출처 : https://yeoncoding.tistory.com/175

- @Aspect가 붙은 클래스안에 @PointCut 과 @Advice가 포함되어 있다.

- 특정 포인트컷을 메소드로 선언하여 어드바이스(@Before)에서 메소드명으로 편하게 사용할 수 있다. 

 

5. 필요한 Dependency 

AOP와 관련된 annotation 들을 사용하기 위해선 다음의 의존성을 build.gradle 파일에 추가해야한다.

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter'
	implementation 'org.springframework.boot:spring-boot-starter-aop'
}

 

6. Advice Annotations

  • @Before : 핵심기능을 호출하기 '전'에 부가기능이 실행된다.
  • @After : 성공/실패 여부와 상관없이 핵심기능을 수행한 후 부가기능이 실행된다. (try catch문 에서 finally 처럼 동작)
  • @Around : 핵심기능의 수행 '전'과 '후' 에 부가기능을 수행한다. 
    예시) 메소드 수행시간 측정, 메소드의 수행 전과 후에 로그를 남기는 경우
  • @AfterReturning : 핵심기능이 정상적으로 동작한 경우 -> 함수의 Return 값을 부가기능에서 사용 가능하다.
  • @AfterThrowing : 핵심기능이 예외를 발생시킨 경우