david's daily developer note

[BE] Spring AOP 본문

[Develop] Web/Back-end

[BE] Spring AOP

mouse-david 2023. 8. 28. 22:15
728x90

스프링 AOP는 스프링 프레임워크에서 제공하는 중요한 기능 중 하나로, 애플리케이션의 여러 부분에서 공통적으로 사용되는 관심사(Concern)를 분리하고 모듈화할 수 있는 방법을 제공한다. AOP는 '관점 지향 프로그래밍'의 약자로, 기존의 객체 지향 프로그래밍(OOP)을 보완하여 코드의 재사용성, 모듈화 및 유지보수성을 개선하는데 도움을 준다.

다음은 AOP의 주요 개념과 용어이다.

Aspect(관점):
애플리케이션의 여러 부분에서 반복되는 관심사를 모듈화한 것으로 로깅, 트랜잭션 관리, 보안 등이 관심사가 될 수 있다.

Join Point(결합 지점): 
애플리케이션 실행 중 특정 시점이나 위치를 가리킵니다. 메서드 호출, 예외 발생 등이 결합 지점의 예시이다.

Advice(조언):
결합 지점에 삽입되어 실행되는 코드 블록을 의미하며, 주요한 조언 유형으로는 'Before', 'After', 'Around' 등이 있다.

 ● Before Advice: 결합 지점의 메서드가 실행되기 전에 실행
 ● After Advice: 결합 지점의 메서드가 실행된 후에 실행
 ● Around Advice: 결합 지점의 메서드 실행을 감싸는 형태로 실행되어, 메서드 호출 전후에 원하는 작업을 수행

Pointcut(지점컷): 
결합 지점의 선택 기준을 정의한 것으로, 어떤 Join Point에 어떤 Advice를 적용할지 결정하는 역할을 합니다.

Weaving(위빙): 
Aspect의 코드가 실제 애플리케이션 코드에 주입되는 과정을 말합니다. 
이는 컴파일 시점, 클래스 로딩 시점, 런타임 시점 등에 수행될 수 있습니다.

다음은 AOP 사용의 기본 설정이다.

1. 의존성 추가

dependencies {
    // Spring AOP
    implementation 'org.springframework.boot:spring-boot-starter-aop'
}

2. Aspect 클래스

package com.example;

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

@Aspect
@Component
public class LoggingAspect {
    @Around("@annotation(com.example.MyLogging)")
    public Object logAnnotatedMethods(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("Before method execution: " + joinPoint.getSignature().getName());

        Object result = joinPoint.proceed();

        System.out.println("After method execution: " + joinPoint.getSignature().getName());
        return result;
    }
}

@Around("@annotation(com.example.MyAnnotation)") 어노테이션은 @MyAnnotation 어노테이션이 붙은 메서드들에 대한 AOP를 정의하는 역할

3. Annotation 정의

package com.example;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyLogging {
}

4. @Annotation 포인트에 Aspect 실행할 수 있도록 등록

package com.example;

import org.springframework.stereotype.Service;

@Service
public class Calculator {
    @MyLogging
    public int add(int a, int b) {
        return a + b;
    }
}

Calculator add함수만 AOP가 실행되도록 @MyLogging Annotation을 등록

4. Aspect 적용

package com.example;

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

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        ApplicationContext context = SpringApplication.run(Application.class, args);
        Calculator calculator = context.getBean(Calculator.class);

        int sum = calculator.add(5, 3);
        System.out.println("Sum: " + sum);
    }
}

AOP와 함수 호출의 차이점은 함수의 경우에는 프로그램의 흐름을 직접 제어하는데, AOP는 해당 함수가 호출되는 시점에 추가 동작이 삽입된다. 따라서, 함수는 함수 내부로 흐름이 이동하고 코드가 순차적으로 실행되는데, Advice는 함수 호출 자체를 하거나, 대체하지 않는다.

@Around함수의 예시로 AOP를 알아보았다. Aspect 실햄 시점을 지정할 수 있는 다른 Annotation은 다음과 같다.

@Aspect
관점(Aspect) 클래스를 정의, 해당 클래스 내에서 Advice 메서드와 Pointcut을 정의하고 관리

@Before
특정 Join Point에서 메서드가 실행되기 전에 실행되는 Advice를 정의

@After
특정 Join Point에서 메서드가 실행된 후에 실행되는 Advice를 정의

@AfterReturning
메서드가 정상적으로 실행된 후에 반환값을 받을 때 실행되는 Advice를 정의

@AfterThrowing
메서드가 예외를 던질 때 실행되는 Advice를 정의, 예외 처리 및 로깅 등에 사용

@Around
메서드 호출을 감싸는 형태로 실행되는 Advice를 정의, 전, 후, 중간에 원하는 작업을 실행할 수 있습니다.

@Pointcut
Advice를 적용할 Join Point를 정의, 복잡한 조인 포인트를 이름으로 정의하고 여러 Advice에서 공유하여 사용

@DeclareParents
새로운 기능을 기존 클래스에 동적으로 추가할 때 사용, Aspect 내에서 인터페이스 구현을 추가하는데 활용

@EnableAspectJAutoProxy
스프링 부트 애플리케이션에서 AOP 자동 프록시를 활성화하는데 사용
 

Spring AOP APIs :: Spring Framework

The previous chapter described the Spring’s support for AOP with @AspectJ and schema-based aspect definitions. In this chapter, we discuss the lower-level Spring AOP APIs. For common applications, we recommend the use of Spring AOP with AspectJ pointcuts

docs.spring.io

 

728x90