관리 메뉴

피터의 개발이야기

[Spring] Spring AOP 개념정리와 Pointcut 표현식 정리 본문

Programming/Spring

[Spring] Spring AOP 개념정리와 Pointcut 표현식 정리

기록하는 백앤드개발자 2024. 8. 25. 10:10
반응형

ㅁ 들어가며

 Spring AOP(Aspect-Oriented Programming)는 애플리케이션의 비즈니스 로직과 공통 관심사를 분리하여 코드의 모듈화를 돕는 프로그래밍 패러다임이다. 이를 통해 코드의 중복을 줄이고 유지보수성을 높일 수 있다.

 

ㅁ AOP의 주요 개념

Aspect
ㅇ Aspect는 여러 객체에 공통으로 적용되는 기능을 모듈화한 것이다.

ㅇ 이는 어드바이스(Advice)와 포인트컷(PointCut)을 결합하여 애플리케이션에 포함되는 횡단 관심사(Cross-cutting Concerns)를 정의한다.

 

Join Point
ㅇ Join Point는 애플리케이션 실행 흐름에서 특정 포인트를 의미하며, AOP가 적용될 수 있는 모든 지점을 나타낸다. 

ㅇ 스프링 AOP에서는 메서드 실행 지점이 주로 Join Point로 사용된다

 

Advice
ㅇ Advice는 Join Point에서 실행되는 코드를 의미한다. 

ㅇ 이는 Aspect를 언제 핵심 코드에 적용할지를 정의하며, 다양한 시점에서 실행될 수 있다.

ㅇ 대표적인 종류로는 Before, AfterReturning, AfterThrowing, After, Around 등이 있다

 

Pointcut
ㅇ Pointcut은 Join Point 중에서 Advice가 적용될 위치를 선별하는 기능을 한다.

ㅇ AspectJ 표현식을 사용하여 지정하며, 스프링 AOP에서는 메서드 실행 지점만 Pointcut으로 선별할 수 있다.

 

Weaving
ㅇ Weaving은 포인트컷으로 결정한 타겟의 Join Point에 Advice를 적용하는 과정이다.

ㅇ 이는 컴파일 타임, 로드 타임, 런타임에 이루어질 수 있으며, 스프링 AOP는 런타임에 프록시 방식을 사용하여 Weaving을 수행한다.


ㅁ Pointcut 표현식

Pointcut 표현식은 특정 Join Point를 선택하기 위해 사용되며, 다양한 지시자가 존재한다:

지시자 설명
execution 메서드 실행 조인 포인트를 매칭한다. 가장 많이 사용되는 지시자이다.
within 특정 타입 내의 조인 포인트를 매칭한다.
args 인자가 주어진 타입의 인스턴스인 조인 포인트를 매칭한다.
this 프록시 객체를 대상으로 하는 조인 포인트를 매칭한다.
target 실제 대상 객체를 대상으로 하는 조인 포인트를 매칭한다.
@annotation 메서드에 특정 어노테이션이 있는 조인 포인트를 매칭한다.

 

@Pointcut("execution(* com.example.service.*.*(..))")
private void serviceLayer() {}

@Before("serviceLayer()")
public void logBefore(JoinPoint joinPoint) {
    System.out.println("Executing: " + joinPoint.getSignature());
}

ㅇ 위 예제는 com.example.service 패키지의 모든 메서드 실행 전에 로그를 출력하는 Aspect를 정의한다. 

ㅇ execution 지시자를 사용하여 서비스 레이어의 메서드를 Pointcut으로 지정하였다.

 

ㅁ Pointcut 표현식 예시

Spring AOP에서 Pointcut 표현식은 특정 Join Point를 선택하여 Advice를 적용할 위치를 결정하는 데 사용된다. Pointcut 표현식은 다양한 지시자와 결합하여 복잡한 조건을 설정할 수 있다. 여기서는 몇 가지 Pointcut 표현식 사용 예시를 정리해보겠다.

ㅇ 모든 공개 메서드 실행

   execution(public * *(..))

 

 - 이 표현식은 모든 public 메서드의 실행을 대상으로 한다.

 

ㅇset으로 시작하는 모든 메서드 실행

execution(* set*(..))

 - 메서드 이름이 set으로 시작하는 모든 메서드 실행에 대해 일치한다.


ㅇ 특정 인터페이스에 정의된 모든 메서드 실행

execution(* com.xyz.service.AccountService.*(..))

 - AccountService에 정의된 모든 메서드의 실행을 대상으로 한다.


ㅇ 특정 패키지에 정의된 메서드 실행

execution(* com.xyz.service.*.*(..))

 

 - com.xyz.service 패키지에 정의된 모든 메서드 실행을 대상으로 한다.


ㅇ 특정 패키지 및 하위 패키지에 정의된 메서드 실행

execution(* com.xyz.service..*.*(..))

 - com.xyz.service 패키지 및 그 하위 패키지에 정의된 모든 메서드 실행을 대상으로 한다.

ㅇ 특정 패키지 내의 모든 조인 포인트

within(com.xyz.service.*)

 - com.xyz.service 패키지 내의 모든 조인 포인트를 대상으로 한다.

ㅇ 특정 인터페이스를 구현하는 프록시의 모든 조인 포인트

this(com.xyz.service.AccountService)

 - AccountService 프록시가 인터페이스를 구현하는 모든 조인 포인트를 대상으로 한다.

ㅇ 특정 애너테이션이 있는 대상 객체의 모든 조인 포인트

@target(org.springframework.transaction.annotation.Transactional)

@Transactional 애너테이션이 있는 대상 객체의 모든 조인 포인트를 대상으로 한다.

ㅇ 특정 이름을 가진 스프링 빈의 모든 조인 포인트

   bean(tradeService)

   `tradeService`라는 이름을 가진 스프링 빈의 모든 조인 포인트를 대상으로 한다.

ㅇ 와일드카드 표현식을 사용한 스프링 빈의 모든 조인 포인트

bean(*Service)


이름이 *Service로 끝나는 모든 스프링 빈의 조인 포인트를 대상으로 한다.

이러한 Pointcut 표현식은 다양한 조합을 통해 복잡한 조건을 설정할 수 있으며, 이를 통해 특정 상황에서만 Advice를 적용할 수 있다. Pointcut 표현식은 AOP의 강력한 기능 중 하나로, 코드의 모듈화를 돕고 유지보수성을 높인다.

참조:  [Spring] 스프링 AOP 포인트컷(Pointcut) 표현식 정리

 

ㅁ AOP의 프록시 방식의 작동원리

Spring AOP는 프록시 방식을 사용하여 애플리케이션의 핵심 기능과 부가 기능을 분리하고 모듈화한다. 프록시 패턴은 객체를 직접 참조하는 대신, 해당 객체를 대리하는 프록시 객체를 통해 접근하는 방식이다. 이를 통해 공통 관심사를 코드의 여러 부분에 일관되게 적용할 수 있다.

ㅇ 프록시 객체 생성

  Spring AOP는 런타임 시점에 프록시 객체를 생성한다. 이 프록시 객체는 실제 객체를 참조하며, 메서드 호출 시 프록시 객체가 먼저 호출된다. 프록시 객체는 실제 메서드 호출 전후에 추가적인 로직을 수행할 수 있는 구조를 제공한다.

 

ㅇ 프록시를 통한 호출

  AOP가 적용된 메서드는 항상 프록시를 통해 호출된다. 프록시 객체는 어드바이스(Advice)를 먼저 실행하고, 이후 실제 대상 객체의 메서드를 호출한다. 이 과정에서 프록시를 거치지 않고 직접 객체를 호출하면 AOP가 적용되지 않는 문제가 발생할 수 있다.

 

ㅇ 프록시 패턴의 장점

  프록시 패턴을 사용하면 공통된 기능을 여러 객체에 일괄적으로 추가할 수 있다. 예를 들어, 로깅, 트랜잭션 관리, 보안 등의 기능을 프록시 객체를 통해 쉽게 구현할 수 있다. 이는 코드의 중복을 줄이고 유지보수성을 높이는 데 기여한다.


ㅇ CGLIB와 JDK 동적 프록시

  Spring AOP는 기본적으로 CGLIB를 사용하여 프록시 객체를 생성한다. CGLIB는 클래스 기반의 프록시를 생성하며, 인터페이스가 없는 클래스에도 적용할 수 있다. 반면, JDK 동적 프록시는 인터페이스 기반으로 프록시를 생성한다.

 

CGLIB(Code Generator Library)란?
코드 생성 라이브러리로서 런타임에 동적으로 자바 클래스의 프록시를 생성해주는 기능을 제공한다.
인터페이스가 아닌 클래스에 대해서 동적 프록시를 생성할 수 있다.

 

ㅁ 마무리

 Spring AOP와 Pointcut을 활용하면 코드의 중복을 줄이고, 공통 관심사를 효과적으로 관리할 수 있다. 이를 통해 애플리케이션의 구조를 더 명확하게 하고 유지보수성을 높일 수 있다.

 

ㅁ 함께 보면 좋은 사이트

 [Spring] AOP 용어 및 개념 정리

[Spring] 스프링 AOP 포인트컷(Pointcut) 표현식 정리

반응형
Comments