본문 바로가기
내일배움캠프/내일배움캠프

[내일배움캠프] TIL : 관점 지향 프로그래밍 AOP

by TIP__ 2024. 11. 18.

AOP

AOP(Aspect-Oriented Programming, 관점 지향 프로그래밍)은 제가 이해한 대로 표현하자면

"여러 클래스나 메소드에서 반복적으로 사용되는 코드(CrossCutting Concerns, 흩어진 관심사)를 분리하여 모듈화하는 것"

이라고 말할 수 있을 것 같습니다.
이를 통해 코드의 가독성을 올리고 유지보수가 좀 더 쉬워질 것이라고 생각합니다.

AOP의 주요 개념

-. Aspect
: 흩어진 관심사를 모듈화한 단위입니다.

 

-. Join Point
: AOP가 적용될 수 있는 지점을 말합니다. 메서드 호출, 필드 접근, 예외 처리 등이 해당 지점이 될 수 있습니다.
: Spring AOP에서는 메서드 실행만이 조인 포인트로 지원됩니다.

 

-. Pointcut
: AOP를 적용할 실제 지점을 정의하는 표현식입니다.
: Join Point 중에서 실제로 AOP가 실행될 곳을 결정할 수 있습니다.

 

-. Advice
: 실제로 수행되는 코드를 말합니다.
: Advice는 Pointcut을 트리거로 삼아 실행됩니다.
: Advice의 종류

  • Before : 메서드 실행 전 실행
  • After : 메서드 실행 후 실행
  • After Returning : 메서드가 정상적으로 반환된 후 실행
  • After Throwing : 메서드에서 예외가 발생한 후 실행
  • Around : 메서드 실행 전/후 실행
@Aspect
@Component
public class LoggingAspect {

    @Around("execution(* com.example.service.*.*(..))")
    public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();

        // 메서드 실행
        Object result = joinPoint.proceed();

        long elapsedTime = System.currentTimeMillis() - start;
        System.out.println(joinPoint.getSignature() + " executed in " + elapsedTime + "ms");

        return result;
    }
}

 

-.Weaving
: Aspect와 대상 객체를 결합하는 과정입니다.


Spring AOP의 특징

-. 프록시 기반 구현
: Spring AOP는 프록시 객체를 생성하여 Aspect를 적용합니다.
: 프록시는 대상 객체의 메서드를 호출하기 전에 Aspect의 어드바이스를 실행합니다.

  • 프록시 객체
    • 대리자 역할을 하는 객체로 실제 객체를 대신하여 그 객체에 대한 요청을 처리하거나, 요청을 가로채서 추가적인 작업을 수행하는 객체입니다.
    • Spring AOP에서 핵심적인 역할을 하며, Aspect와 실제 객체(비즈니스 로직) 사이에서 동작합니다.
    • 즉, 프록시 객체는 대리자 역할을 하는 객체를 생성하여 Aspect로 지정한 작업을 수행한다고 이해했습니다.

-. 런타임 Weaving
: Spring AOP는 런타임 시점에 Aspect를 동적으로 적용합니다.
: 이는 Java의 Proxy 클래스와 CGLIB를 사용하여 구현됩니다.

  • 프록시 클래스
    • 객체 지향 프로그래밍에서 다른 객체에 대한 접근을 제어하기 위해 사용되는 클래스입니다.
    • 실제 객체를 대리하거나 대신하여 작업을 수행하는 역할을 하며 주로 성능 최적화나 보안, 접근 제어, 지연 로딩 등의 목적으로 사용됩니다.
    • 프록시 클래스는 Aspect 뿐 아니라 실제 비즈니스 로직까지 포함하는 클래스입니다.
  • CGLIB
    • 프록시 클래스 생성을 지원하기 위해 사용되는 라이브러리입니다.
    • 특정 클래스의 프록시 객체를 생성함으로써 AOP기능을 구현하거나 클래스에 추가적인 동작을 부여하는 데 사용됩니다.

-. 메서드 실행에만 적용 가능
: Spring AOP는 메서드 실행 Join Point에만 적용할 수 있습니다.


Spring AOP 사용

Aspect 정의
-. @Aspect : 이 클래스가 Aspect임을 선언
-. @Before : 메서드 실행 전 실행
-. excution : Pointcut 표현식

  • 해당 예제에서 사용된 표현식 execution(* com.example.service..(..))
    • * : 모든 리턴 타입
    • com.example.service.* : 특정 패키지의 모든 클래스
    • .*(..) : 모든 메서드 및 모든 파라미터
execution(modifiers-pattern? return-type-pattern declaring-type-pattern? method-name-pattern(param-pattern) throws-pattern?)

-. 표현식 중 ?는 해당 부분이 선택적임을 나타냅니다.

-. modifiers-pattern (접근 제한자 패턴)
 : 메서드의 접근 제한자를 지정
 : public, private, protected, * 등
 : 해당 부분은 선택적이며 생략이 가능합니다.
 
-. return-type-pattern (반환 타입 패턴 )
 : 메서드의 반환 타입을 지정
 : void, String, com.exmaple..* 등

-. declaring-type-pattern (선언된 타입 패턴)
 : 메서드가 선언된 클래스나 인터페이스를 지정
 : 해당 부분은 선택적이며 생략이 가능합니다.

-. method-name-pattern (메서드 이름 패턴)
 : 적용할 메서드의 이름을 지정

-. param-pattern (파라미터 패턴)
 : 메서드의 파라미터 타입을 지정합니다.
 : ()는 파라미터가 없는 메서드와 매칭됩니다.

-. throws-pattern (예외 패턴)
 : 메서드가 던질 수 있는 예외 타입을 지정합니다.
 : 해당 부분은 선택적이며 생략이 가능합니다.

 

Spring AOP 사용 예제


import org.aspectj.lang.annotation.Aspect;  
import org.aspectj.lang.annotation.Before;  
import org.springframework.stereotype.Component;

@Aspect  
@Component  
public class LoggingAspect {
	@Before("execution(* com.example.service..(..))")
	public void logBeforeMethod() {
	System.out.println("메서드 실행 전 로깅...");
	}
}

 


AOP의 장/단점

장점

-. 중복 코드 제거 : 공통된 기능을 모아서 모듈화함으로 중복되는 코드 사용을 줄입니다.
-. 모듈성 향상 : 핵심 비즈니스 로직과 공통 기능을 분리함으로 코드의 가독성과 유지보수성을 향상시킵니다.
-. 유연성 : 특정 지점에 원하는 작업을 추가하거나 수정하기 쉽습니다.

단점

-. 코드의 복잡성 : 비즈니스 로직과 공통 기능이 분리되어있음으로 때로는 코드의 흐름을 이해하기 여러울 수 있습니다.
-. 런타임 성능 저하 : Spring AOP는 프록시 객체를 사용하기 때문에 런타임 오버헤드가 발생합니다.
-. 디버깅의 어려움 : Aspect가 동적으로 결합되므로 디버깅 시 흐름을 추적하기 어렵습니다.

댓글