본문 바로가기
SPRING/개념

[ 개념 ] 스프링(spring) AOP란 어노테이션 어드바이스

by hak0205 2023. 2. 10.
반응형

AOP란

AOP는 Aspect Oriented Programming의 약자로 관점 지향 프로그래밍이라고 부릅니다. 관점 지향은  로깅, 보안 또는 트랜잭션 로직을 기준으로 핵심적인 관점, 부가적인 관점으로 나누어서 보고 그 관점을 기준으로 모듈화 하겠다는 것입니다.
 
여기서 모듈화는 어떤 공통된 로직이나 기능을 하나의 단위로 묶는 것을 말하며 예시는 다음과 같습니다. 핵심적인 관점은 비즈니스 로직이 될 수 있고, 부가적인 관점은 핵심 로직을 실행하기 위해 행해지는 데이터베이스 연결, 로깅, 파일 입출력 등이 될 수 있습니다.
 
AOP를 사용하면 코드를 전체 코드베이스에 분산시킬 필요 없이 명확하고 간결한 방식으로 특정 정책을 시행하는 코드를 작성할 수 있습니다. 코드 중복을 줄이고 코드 유지 관리성을 높일 수 있으며 횡단관심사(Corsscutting Concerns)를 보다 쉽게 관리할 수 있습니다.
 
간단히 말해서 개발자가 각 개별 부분에서 해당 코드를 반복할 필요 없이 애플리케이션의 여러 부분에 적용할 수 있는 재사용 가능한 코드를 작성할 수 있습니다.


여기서 잠깐, 횡단관심사(Corsscutting Concerns)란?

핵심적인 기능이 아닌 중간에 삽입되어야 할 기능들 관심들을 횡단관심사(Corsscutting Concerns)이라고 합니다.
예를 들면 로깅, 보안, 트랜잭션 처리 등 비즈니스로직의  핵심적인 기능이 아닌 다양한 횡단 관심이 발생할 수 있습니다.
 

예제

 

@Aspect
public class LoggingAspect {
    @Before("execution(* com.example.myapp.*.*(..))")
    public void logMethodCall(JoinPoint joinPoint) {
        System.out.println("Calling method: " + joinPoint.getSignature().getName());
    }
}

이 예제에서는 Spring의 "@Aspect" 주석을 사용하였으며 관점임을 나타내는 "LoggingAspect" 클래스를 정의했습니다.
 
또한 pointcut 표현식 "execution (* com.example.myapp .. (..))"과 일치하는 메서드 앞에 실행되는 "logMethodCall"메서드를 정의했습니다. 이 표현식은 "com.example.myapp"패키지 또는 하위 패키지의 모든 메서드와 일치합니다.  
 
응용 프로그램이 실행되고이 pointcut 표현식과 일치하는 메소드가 호출되면 "logMethodCall"메서드가 먼저 실행되어 호출되는 메서드의 이름이 인쇄됩니다. 즉, com.example.myapp 패키지 밑에 포함되어 있는 하위 메서드라면 logMethodCall메서드가 실행됩니다.
 

AOP 어노테이션(Annotation) 어드바이스

스프링 AOP에서 어노테이션(Annotation) 어드바이스는 객체의 메서드 호출에 적용되는 추가 동작입니다. 

  1. Before advice - 메서드 호출 전에 실행됩니다..
  2. After returning advice - 메소드 호출이 결과를 반환한 후 실행됩니다.
  3. After throwing advice - 메서드 호출이 예외를 던진 후 실행됩니다.
  4. After advice - 메서드 호출 후에 실행됩니다(정상적으로 반환되거나 예외가 발생한 경우).
  5. Around advice - 메서드 호출을 래핑하고(감싸고) 실제 메서드 호출 전후의 호출을 가로챌 수 있습니다.

1. Before advice

@Aspect
@Component
public class LoggingAspect {
    @Before("execution(* com.example.myapp.UserService.save(..))")
    public void logUserSave(JoinPoint joinPoint) {
        System.out.println("Saving user...");
    }
}

이 예제에서는 UserService의 save() 메소드가 호출되기 전에 메시지를 기록하는 Before advice를 정의했습니다.
 

2. After returning advice

@Aspect
@Component
public class LoggingAspect {
    @AfterReturning(pointcut = "execution(* com.example.myapp.UserService.findUserById(..))", returning = "user")
    public void logUserFound(User user) {
        System.out.println("Found user: " + user.getName());
    }
}

 
이 예에서는 UserService의 findUserById() 메서드가 결과를 반환한 후 메시지를 기록하는 AfterReturning 조언을 정의했습니다.
 

3. After throwing advice

@Aspect
@Component
public class LoggingAspect {
    @AfterThrowing(pointcut = "execution(* com.example.myapp.UserService.deleteUserById(..))", throwing = "ex")
    public void logUserDeletionError(Exception ex) {
        System.out.println("Error deleting user: " + ex.getMessage());
    }
}

 
이 예에서는 UserService의 deleteUserById() 메서드가 예외를 발생시킨 후 메시지를 기록하는 AfterThrowing 조언을 정의했습니다.
 

4. After advice

@Aspect
@Component
public class LoggingAspect {
    @After("execution(* com.example.myapp.UserService.updateUser(..))")
    public void logUserUpdate(JoinPoint joinPoint) {
        System.out.println("User updated.");
    }
}

 
이 예에서는 UserService의 updateUser() 메서드가 호출된 후 메시지를 기록하는 After 조언을 정의했습니다.

5. Aound advice

@Aspect
@Component
public class LoggingAspect {
    @Around("execution(* com.example.myapp.UserService.save(..))")
    public Object logUserSave(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("Saving user...");
        Object result = joinPoint.proceed();
        System.out.println("User saved.");
        return result;
    }
}

 
이 예에서는 UserService의 save() 메서드를 래핑하고 메서드 호출 전후에 메시지를 기록하는 Around advice을 정의했습니다. ProceedingJoinPoint 인수는 실제 메서드 호출을 진행하는 데 사용됩니다.
 

장점

Spring AOP(Aspect-Oriented Programming) 장점은 다음과 같습니다.

  1.  교차적 관심사의 모듈화 : AOP를 사용하면 교차적 관심사를 모듈화 하고 캡슐화할 수 있습니다. 로깅, 보안 또는 트랜잭션 관리와 같은 코드를 재사용 가능한 구성 요소로 통합하여 코드를 보다 쉽게 관리하고 유지 관리할 수 있습니다.
  2. 코드 유지 관리성 향상: 핵심 비즈니스 로직을 사용하면 각 관점에 명확하고 잘 정의된 책임이 있으므로 코드를 이해, 유지 및 수정하기 쉽게 만들 수 있습니다.
  3. 코드 중복 감소 : AOP 사용, 기존의 객체 지향 프로그래밍 기술을 사용하여 동일한 교차 편집 문제를 구현하는 경우 필요한 애플리케이션의 여러 위치에서 코드 복제를 피할 수 있습니다.
  4. 향상된 성능 : 관점은 런타임에 대상 객체에 통합되므로 상속 또는 위임과 같은 기존 접근 방식을 사용하는 것과 비교하여 관점의 성능 오버헤드를 최소화할 수 있습니다. 
  5. 선언형 프로그래밍 : Spring AOP는 선언형 프로그래밍 모델을 제공합니다. 여기서 코드가 아닌 구성을 사용하여 관점의 동작을 정의하면 애플리케이션을 더 쉽게 관리하고 유지 관리할 수 있습니다.
  6. AspectJ 지원 : Spring AOP는 강력하고 유연한 AOP 프레임워크인 AspectJ에 대한 지원을 제공하여 애플리케이션에서 다양한 AOP 기능을 사용할 수 있습니다.
  7. 다른 Spring 기능과의 통합 : Spring AOP는 Spring IoC, Spring MVC 및 Spring Data와 같은 다른 Spring 기능과 완전히 통합되어 애플리케이션에서 AOP를 원활하게 사용할 수 있습니다.

 

단점

Spring AOP(Aspect-Oriented Programming) 단점은 다음과 같습니다.

  1. 복잡성 : AOP는 특히 개념을 처음 접하는 개발자에게 이해하고 사용하기 복잡할 수 있습니다. AOP는 또한 응용 프로그램에 추상화 계층을 추가하여 코드의 제어 흐름을 디버깅하고 이해하는 것을 더 어렵게 만들 수 있습니다.
  2. 성능 오버헤드 : Spring AOP는 관점의 성능 오버헤드를 최소화하지만, 런타임에 관점을 대상 객체로 엮는 프로세스는 특히 크고 복잡한 응용프로그램의 경우 응용프로그램에 약간의 오버헤드를 추가할 수 있습니다.
  3. 도구 지원 부족 : AOP로 작업하는 데 도움이 되는 몇 가지 도구가 있지만 AOP에 대한 지원은 기존 객체 지향 프로그래밍만큼 광범위하지 않으며 속도를 높이려면 추가 교육이나 리소스에 투자해야 할 수 있습니다.
  4. 단위 테스트 간섭 : AOP를 사용하여 코드에 관점을 적용하면, 관점이 코드의 정상적인 제어 흐름을 방해할 수 있기 때문에 단위 테스트를 작성하고 실행하는 것이 더 어려워질 수 있습니다.
  5. 적용 제한 : AOP는 모든 유형의 문제에 적용되는 것은 아니며 모든 사용 사례에 최선의 선택은 아닐 수 있습니다. 요구 사항을 신중하게 고려하고 특정 요구 사항에 가장 적합한 접근 방식을 선택해야 합니다.
  6. 오용 가능성 : AOP를 잘못 사용하면 코드를 이해, 유지 및 디버그 하기가 더 어려워지고 커플링이 증가하고 유연성이 저하될 수 있습니다. AOP를 신중하고 신중하게 사용하고 코드에 사용하기 전에 개념을 확실히 이해하는 것이 중요합니다.

 
감사합니다

 
 
 
 
반응형

댓글