[Spring] AOP 개념 및 정리

2022. 6. 5. 17:41Web/Spring

[Spring] AOP 개념 및 정리

스터디를 진행하면서 배운 AOP에 대해 정리하고자한다. 추후에 Spring 고급편을 진행하면서 배우게 되는 심화 내용은 따로 정리할 예정이다. 지금 내용은 Spring에 대해 전반적인 내용을 다루는 기본편 강의에서 좀 더 알아보고자 정리했던 내용을 적으려고 한다. 

 

AOP - Aspect Oriented Programming

관점 지향 프로그래밍이라고 한다. 관점 지향 프로그래밍의 경우 공통 관심사항과 핵심 관심사항을 분리하여 프로그래밍을 하는것을 말한다. 예시(접은 글)에서 나온 시간 측정 로직을 공통 관심사항이라 하자. 그리고 나머지 역할을 핵심 관심사항이라 하자. 

더보기
기존 코드에 새로운 로직 추가

공통 관심 사항이 구현체 내부로 들어갔는지 안들어갔는지의 유무로 나뉘어지는데 외부에서 따로 주입하는 식의 방식을 AOP라고 한다.

 

AOP 구성요소

  • Aspect : 핵심기능을 제외한 나머지 공통 관심부분을 모듈화
  • Target : Aspect를 적용하는 곳 ( Ex  :  클래스 / 메서드 )
  • Advice : 활용하고자 하는 부분 ( EX: 스탑워치) 구현체
  • PointCut :  JoinPoint의 상세한 내용을 정의 , 즉 바라는 시점을 정함
  • JoinPoint : 구현체인 Advice가 사용될 시점을 정하는 도구
package hello.hellospring.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

@Aspect // AOP 인식을 위한 어노테이션
@Component  // 스프링 빈으로 등록을 위한 어노테이션

public class TimeTraceAop {

	// PointCut지점과 PointCut이 적용되는 부분을 위한 어노테이션
    @Around("execution(* hello.hellospring.service..*(..))")
    
    //advice 구현 후 사용될 시점을 정하는 JoinPoint
	public Object execute(ProceedingJoinPoint joinPoint) throws Throwable { 
    
        long start = System.currentTimeMillis();
        System.out.println("Start :" + joinPoint.toString());
        try{
            return joinPoint.proceed();
        }finally {
            long finish = System.currentTimeMillis();
            long timeMs = finish - start;
            System.out.println("End : " + joinPoint.toString() + " " + timeMs + "ms");
        }
    }
}

 

PointCut의 지점

PointCut의 경우 @Around 말고도 4가지의 다른 어노테이션이 존재한다. 

pointcut 지점

- advice 기능 수행 이전 - 
@Before  : 타켓 지정된 타켓 메서드가 호출되기전 advice 기능 수행

- advice 기능 수행 이후 - 
@After : 타켓 메서드의 결과에 상관없이 타켓메서드가 완료가 되면 어드바이스 기능 수행

@AfterReturning : 타켓 메서드가 성공적으로 결과값을 반환 후에 어드바이스 기능을 수행

@AfterThrowing : (정상적 반환 이후) : 타켓 메서드가 수행 중 예외를 던지면 advice 기능 수행

- advice 기능 전 후 - 
@ Around : advice가 타켓 메서드를 감싸서 타켓 메서드를 호출 전과 후로 advice 기능을 수행.
 - 홀로 다른 메서드들을 구현가능

 

JoinPoint /  ProceedingJoinPoint

JoinPoint 
- 메서드의 매개 변수, 반환 값 또는 throw와 같이 지정된 조인 지점에서 사용할 수 있는 상태에 대한 반사 엑세스를 제공하는 인터페이스


ProceedingJoinPoint
- JoinPoint에서 Proceed() 메서드를 추가한 확장 메서드이다. 
호출이 되면 코드의 실행이 다음 advice 혹은 타겟 메서드로 이동
즉 코드의 흐름을 제어하고 추가 호출을 진행할지 여부를 결정하는 권한 제공 - > around에서만 사용가능 

 

따라서 ProceedingJoinPoint의 경우에서는 좀 더 유동적인 AOP 작성이 가능하다.

 

 

프록시 패턴

AOP의 경우 프록시 패턴을 바탕으로 만들어진다. 

프록시 패턴으로 만들어진 프록시 객체를 생성하여 요청을 전달 받고 후에 joinPoint의 proceed() 메서드로 실제 객체를 호출 및 동작을 관리한다. 

 

- 장점

• 크기가 큰 객체를 로딩전에 미리 참조 가능
• 실제 객체의 중요 메서드들 숨기고 인터페이스를 통해 노출 가능
• 접근하려는 객체에 관해 사전 처리가 가능

- 단점
• 성능의 저하

-  프록시의 경우 가상의 객체를 통해 본 객체를 호출하는 역할이다. 이러한 역할로 인해 다수의 요청이 동시다발적으로 들어온다면 성능이 저하되는 경우가 존재한다