Don't give up!

[SpringBoot] Spring과 AOP 본문

Spring Boot

[SpringBoot] Spring과 AOP

Heang Lee 2021. 8. 13. 20:32

관점 지향 프로그래밍(Aspect-Oriented Programming, AOP)

AOP는 각 기능들에 흩어져 있는, 그러나 독립적으로 분리하기 어려운 부가 기능들을 모듈화하는 프로그래밍 기법입니다.

공통된 부가 기능들을 재사용함으로써 애플리케이션 전체에 흩어진 공통 기능을 하나의 장소에서 관리할 수 있고 서비스 모듈로 하여금 다른 모듈을 신경쓰지 않도록 한다는 장점을 가지고 있습니다.

왜 필요한가?

객체지향 프로그래밍(OOP)에서는 단일 책임 원칙(Single Responsibility Principle, SRP)에 따라 하나의 클래스는 하나의 책임만 가져야 하며 개방 폐쇄 원칙(Open-Closed Principle, OCP)에 의하여 확장에는 열려 있으나 변경에는 닫혀 있어야 합니다.

public class UserService {
  private UserRepository repository;
  
  public List<User> getUsers() {
    long start = System.currentTimeMillis();
    List<User> users = repository.findAll();
    long end = System.currentTimeMillis();
    
    System.out.println("수행 시간 : " + (end - start));
    return users;
  }
}

public class BoardService {
  private BoardRepository repository;
  
  public List<Board> getBoards() {
    long start = System.currentTimeMillis();
    List<Board> boards = repository.findAll();
    long end = System.currentTimeMillis();
    
    System.out.println("수행 시간 : " + (end - start));
    return boards;
  }
}

그러나 위와 같은 코드의 경우 하나의 함수가 2개 이상의 행동을 하고 코드가 중복되어 있습니다.

상속을 통해 이러한 문제들을 해결할 수도 있겠으나 여러 클래스에 걸쳐 중복되는 부가 기능들이 2개 이상인 경우 이를 해결하기 어렵습니다.

AOP에서는 이러한 부가기능들을 관점(Aspect)로 정의하고 모듈화함으로써 문제를 해결합니다.

스프링 AOP

스프링은 @Aspect 어노테이션으로 부가 기능 모듈을 정의할 수 있으며 다음의 특징을 갖고 있습니다.

  1. 스프링 Bean에만 AOP를 적용할 수 있다.
  2. Proxy 패턴 기반의 AOP 구현체이다. (접근 제어 및 부가기능을 추가하기 위함)
@Target(ElementType.MEHTOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogPerformanceTime{
}

@Component
@Aspect
public class PerformanceAspect {
  @Around("@annotation(LogPerformanceTime)")
  public Object logPerformanceTime(ProceedingJoinPoint joinPoint) throws Throwable {
    Object result = null;
    try {
      long start = System.currentTimeMillis();
      result = joinPoint.proceed();
      long end = System.currentTimeMillis();
      System.out.println("수행 시간 : "+ (end - start));
    } catch (Throwable throwable) {
      System.out.println("Exception");
    }
    return result;
  }
}

public class UserService {
  private UserRepository repository;
  
  @LogPerformanceTime
  public List<User> getUsers() {
    List<User> users = repository.findAll();
    return users;
  }
}

public class BoardService {
  private BoardRepository repository;
  
  @LogPerformanceTime
  public List<Board> getBoards() {
    List<Board> boards = repository.findAll();
    return boards;
  }
}

부가기능 모듈(Aspect) PerformanceAspect는 애너테이션 또는 XML로 빈 등록을 하여 Spring에 정의할 수 있습니다.

Aspect의 부가기능이 적용될 곳(Target)은 @Around와 같이 부가기능에 붙은 애너테이션에 PointCut 표현식을 넣어 선언합니다.

@Around 애너테이션은 AOP의 Advice입니다.

Aspect가 실행될 위치를 알리고 언제 실행될 것인지를 애너테이션 자체로서 정의합니다.

애너테이션 실행되는 위치
@Before Target 메서드가 호출되기 전에 Advice 기능을 수행
@After Target 메서드의 결과에 관계없이 완료되면 Advice 기능을 수행
@AfterReturning Target 메서드가 성공적으로 결과값이 반환된 후 기능을 수행
@AfterThrowing Target 메서드가 예외를 던지면 기능을 수행
@Around Target 메서드 전/후에 기능을 수행

Advice가 수행될 Target은 코드와 같이 애너테이션으로 지정하는 방법, PointCut 표현식으로 클래스 혹은 메소드를 직접 지정하는 방법이 있습니다.

지정자 설명
args() 메서드의 인자가 해당 타입인 경우
@args() 메서드의 인자가 해당 어노테이션 타입을 갖는 경우
execution() 해당 경로의 패키지, 클래스 또는 메소드
within() 해당 패키지 내 클래스와 인터페이스가 가진 메소드
this() Target 메서드가 지정된 빈 타입의 인스턴스인 경우
target() 지정된 (빈 타입이 아닌) 타입의 인스턴스인 경우
@target() 객체의 클래스에 지정된 타입의 어노테이션이 있는경우
@annotation 지정된 어노테이션이 Target 메서드에 지정된 경우

 

출처

AOP 정리 (1) (tistory.com)

 

AOP 정리 (1)

현재 신입사원 분들의 입사로 Spring에서 중요한 개념들에 대해 한번 정리하려고 작성하게 되었습니다. Spring의 가장 중요한 개념 중 하나인 AOP를 제 나름의 이해로 정리하였습니다. 틀린 내용이

jojoldu.tistory.com


[Spring] 스프링 AOP (Spring AOP) 총정리 : 개념, 프록시 기반 AOP, @AOP (tistory.com)

 

[Spring] 스프링 AOP (Spring AOP) 총정리 : 개념, 프록시 기반 AOP, @AOP

| 스프링 AOP ( Aspect Oriented Programming ) AOP는 Aspect Oriented Programming의 약자로 관점 지향 프로그래밍이라고 불린다. 관점 지향은 쉽게 말해 어떤 로직을 기준으로 핵심적인 관점, 부가적인 관점으..

engkimbs.tistory.com