AOP

Dong·2024년 11월 20일

Spring

목록 보기
5/8

https://docs.spring.io/spring-framework/reference/core/aop/introduction-defn.html

Spring AOP(Aspect-Oriented Programming)는 스프링 프레임워크에서 제공하는 관점 지향 프로그래밍 기능으로, 주로 공통 기능을 애플리케이션 코드와 분리하여 재사용성을 높이고 코드의 중복을 줄이기 위한 기법이다. AOP는 특정 기능(로깅, 트랜잭션 관리, 예외 처리 등)을 여러 클래스나 메서드에 적용해야 할 때 유용하게 사용할 수 있다.

AOP의 기본 개념

  • 관점(Aspect): 공통 기능을 정의한 모듈. 로깅, 트랜잭션 관리와 같은 횡단 관심사를 모듈화한 것
  • 조인 포인트(Join Point): 애플리케이션에서 Aspect가 적용될 수 있는 지점을 의미하고 보통 메서드 호출이 조인 포인트로 사용된다.
  • 어드바이스(Advice): Aspect가 조인 포인트에서 수행하는 작업으로, 어떤 시점에 어떤 기능을 실행할지 정의함. Ex) 메서드 실행 전, 실행 후, 예외 발생 시 등.
  • 포인트컷(Pointcut): 어드바이스가 적용될 조인 포인트를 필터링하는 조건. 특정 클래스나 메서드에만 Aspect를 적용할 수 있게 한다.
  • 타겟(Target): Aspect가 적용되는 실제 객체로, 주로 비즈니스 로직을 포함하는 객체.
  • 프록시(Proxy): 스프링 AOP는 프록시 패턴을 사용하여, 타겟 객체의 메서드 호출 시 프록시 객체를 통해 Aspect를 적용
  • 위빙(Weaving): Aspect와 타겟 객체의 조인 포인트를 결합하는 과정으로, 실제로 AOP 기능이 적용되는 시점을 나타냄. 위빙이 완료되면 타겟 객체의 메서드 호출 시 Aspect가 결합된 프록시 객체가 호출되어 어드바이스가 실행

Spring AOP의 작동 방식

스프링 AOP는 프록시 패턴을 사용하여, 프록시 객체가 타겟 객체를 대신하여 호출을 가로채고 필요한 Aspect를 적용. 메서드가 호출되면 프록시 객체가 해당 호출을 가로채어 Aspect가 먼저 실행되도록 하는 방식이다. 스프링 AOP는 런타임에 프록시 객체를 생성하여 AOP를 적용하므로, 주로 메서드 호출에 대한 조인 포인트를 지원한다.

AOP 적용 시점에 따른 Advice의 종류

  1. Before: 메서드 실행 전에 실행되는 어드바이스
  2. After Returning: 메서드가 정상적으로 실행된 후에 실행되는 어드바이스
  3. After Throwing: 메서드 실행 중 예외가 발생했을 때 실행되는 어드바이스
  4. After: 메서드 실행 후(성공 여부와 상관없이) 실행되는 어드바이스
  5. Around: 메서드 실행 전후에 모두 실행되는 어드바이스

의존성 추가

https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop

build.gradle 에 추가

    // Spring AOP
    implementation 'org.springframework.boot:spring-boot-starter-aop:3.3.5'

application properties 에 추가

# Spring AOP
spring.aop.auto=true
spring.aop.proxy-target-class=true

Spring AOP를 사용하는 예제

아래 예제에서는 메서드 실행 시간을 로깅하는 Aspect를 만들어 보자

1. Aspect 클래스 정의

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

@Aspect  // Aspect로 정의
@Component  // 스프링 빈으로 등록
public class LoggingAspect {

    @Around("execution(* com.example.service.*.*(..))") // 포인트컷 정의
    public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();

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

        long executionTime = System.currentTimeMillis() - start;
        System.out.println(joinPoint.getSignature() + " 실행 시간: " + executionTime + "ms");

        return proceed;
    }
}
  1. 포인트컷 정의 (@Around)
  • @Around 어드바이스: 메서드 실행 전후에 특정 작업을 수행할 수 있다.
  • 포인트컷 표현식: "execution(* com.example.service.*.*(..))"com.example.service 패키지 내의 모든 메서드에 대해 Aspect를 적용함

3. 타겟 클래스와 메서드

Aspect가 적용될 SampleService 클래스를 정의

import org.springframework.stereotype.Service;

@Service
public class SampleService {

    public void execute() {
        System.out.println("SampleService 실행 중...");
    }
}

4. 스프링 부트 애플리케이션 설정

스프링 부트 애플리케이션은 기본적으로 @EnableAspectJAutoProxy를 통해 AOP를 활성화하고 이 설정은 @SpringBootApplication에 포함되어 있다.

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

5. 실행 결과

애플리케이션을 실행하면 SampleServiceexecute 메서드를 호출할 때마다 LoggingAspectlogExecutionTime 메서드가 호출되어 실행 시간을 출력

SampleService 실행 중...
void com.example.service.SampleService.execute() 실행 시간: 10ms

AOP 적용 방법 요약

  1. Aspect 정의: @Aspect 어노테이션을 사용해 클래스를 Aspect로 정의하고, @Component로 스프링 빈에 등록
  2. 포인트컷 설정: 포인트컷 표현식(execution 등)을 사용해 Aspect가 적용될 메서드나 클래스 범위를 지정
  3. 어드바이스 설정: @Before, @After, @Around 등 어드바이스 어노테이션을 사용해 실행 시점을 지정하고, 관련 작업을 수행한다.

AOP의 장점과 사용 사례

장점

  • 공통 기능 모듈화: 로깅, 예외 처리, 트랜잭션 관리 등의 공통 기능을 여러 클래스에 중복 작성하지 않고 하나의 Aspect로 관리할 수 있다..
  • 코드 가독성 향상: 핵심 비즈니스 로직에 집중할 수 있도록 도와줌
  • 유지보수성 향상: 공통 기능을 하나의 모듈로 관리할 수 있어 수정이 용이하다.

요약

Spring AOP는 횡단 관심사를 Aspect로 모듈화하여 코드의 재사용성과 가독성을 높이고, 유지보수를 쉽게 할 수 있는 강력한 도구이다. 주로 로깅, 트랜잭션, 예외 처리 등 공통 기능을 관리하는 데 유용하며, 스프링에서 제공하는 어노테이션(@Aspect, @Around, @Before 등)을 활용해 간단하게 적용할 수 있다.

profile
소통을 잘하는 백엔드 개발자가 되기 위해, 꾸준히 성장하고 기록중입니다.

0개의 댓글