본문으로 바로가기
반응형

Java와 Spring Framework에서는 AOP(Aspect-Oriented Programming)라는 강력한 기능을 제공하여, 코드의 중복을 제거하고 특정 기능을 쉽게 확장할 수 있습니다. AOP의 핵심은 Aspect라는 개념인데, 이는 특정 기능을 모듈화하여 코드에서 중복을 제거하고 다양한 곳에서 재사용할 수 있도록 해줍니다.

이 글에서는 Spring AOP를 사용하여 Custom Annotation을 만들고 이를 메서드에 적용하여 Advice(부가기능)을 실행하는 방법에 대해 자세히 설명하겠습니다. 예를 들어, @Logging이라는 Custom Annotation을 만들어, 특정 메서드가 실행될 때마다 자동으로 로그를 기록하는 방법을 알아보겠습니다.

1. Spring AOP 개념과 사용 이유

Spring AOP는 메서드 실행 전후로 추가적인 동작을 처리할 수 있게 해주는 기능입니다. 이를 통해 로깅, 트랜잭션 관리, 권한 체크 등 여러 부가기능을 핵심 비즈니스 로직과 분리하여 코드의 중복을 줄이고, 유지보수를 쉽게 할 수 있습니다.

AOP에서 핵심적인 개념은 다음과 같습니다:

  • Aspect: 하나 이상의 부가기능(로깅, 트랜잭션 등)을 포함하는 모듈.
  • Advice: 실제 부가기능을 구현한 코드.
  • Pointcut: AOP가 적용될 지점(메서드, 클래스 등)을 정의하는 표현식.
  • JoinPoint: Advice가 실행되는 구체적인 지점(메서드 호출 등).

이제 AOP의 동작 원리를 이해했으니, Custom Annotation을 만들고 이를 AOP에서 사용하는 방법을 살펴보겠습니다.


2. Custom Annotation 만들기

먼저, Spring AOP에서 사용할 Custom Annotation을 만듭니다. 이 Annotation은 우리가 적용하고 싶은 메서드에 메타데이터를 추가하는 역할을 합니다. 예를 들어, @Logging이라는 Annotation을 정의하여 메서드가 호출될 때마다 로그를 남기게 만들겠습니다.

Logging Annotation 정의

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

// 메서드에 적용할 수 있는 Annotation
@Retention(RetentionPolicy.RUNTIME)  // 런타임 동안 유지되도록 설정
@Target(ElementType.METHOD)          // 메서드에만 적용
public @interface Logging {
    String value() default "";       // Annotation에 값을 설정할 수 있는 속성
}
 
  • @Retention(RetentionPolicy.RUNTIME): 이 Annotation이 런타임 동안 유지되도록 설정합니다. 이 설정 덕분에 Spring AOP가 Annotation을 읽을 수 있습니다.
  • @Target(ElementType.METHOD): 이 Annotation이 메서드에만 적용될 수 있도록 설정합니다.
  • String value() default "";: Annotation에 value라는 속성을 추가하여, 메서드에 대한 추가 정보를 저장할 수 있습니다.

이렇게 정의된 @Logging Annotation은 특정 메서드에 적용되어, AOP에서 해당 메서드가 호출될 때마다 부가적인 동작을 실행할 수 있게 됩니다.


3. AOP에서 Custom Annotation 사용하기

이제 우리가 만든 @Logging Annotation을 활용해, AOP Advice를 정의하여 메서드 실행 시 로그를 기록하도록 하겠습니다.

Aspect 클래스 정의

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

// @Aspect: AOP 기능을 제공하는 클래스임을 나타냄
// @Component: Spring Bean으로 등록
@Aspect
@Component
public class LoggingAspect {

    // @Before: 해당 메서드 실행 전에 로그를 남기기 위한 Advice
    @Before("@annotation(logging)")  // 메서드에 @Logging이 붙은 경우
    public void logBefore(JoinPoint joinPoint, Logging logging) {
        // 메서드 정보 출력
        System.out.println("Logging before method: " + joinPoint.getSignature());
        
        // @Logging에서 설정한 value 속성 값 출력
        System.out.println("Annotation value: " + logging.value());
    }
}

코드 설명

  1. @Aspect: 이 클래스가 AOP의 Aspect 역할을 한다는 것을 나타냅니다. 이 클래스를 통해 AOP의 핵심 동작을 정의합니다.
  2. @Component: 이 클래스를 Spring의 Bean으로 등록하여, Spring 컨텍스트에서 관리되도록 합니다.
  3. @Before("@annotation(logging)"): @Logging Annotation이 붙은 메서드가 호출될 때, 이 logBefore 메서드가 실행되도록 설정합니다. logging은 @Logging Annotation의 객체를 참조하는 변수로, logging.value()를 통해 Annotation의 속성값에 접근할 수 있습니다.
  4. JoinPoint: JoinPoint는 AOP에서 메서드 실행 시점의 정보(메서드 시그니처, 메서드 파라미터 등)를 제공하는 객체입니다.

이렇게 정의된 LoggingAspect는 @Logging Annotation이 붙은 모든 메서드 실행 전에 자동으로 로그를 출력합니다.


4. @Logging Annotation 적용하기

이제 실제로 @Logging Annotation을 메서드에 적용하여, AOP가 어떻게 동작하는지 확인해보겠습니다.

대상 클래스에서 @Logging 사용

import org.springframework.stereotype.Service;

@Service
public class MyService {

    // @Logging Annotation을 사용하여 로그를 남기고자 하는 메서드에 적용
    @Logging("This is a test log")  // value 속성에 값 전달
    public void myMethod() {
        System.out.println("Executing myMethod");
    }

    // 다른 메서드는 AOP 영향을 받지 않음
    public void anotherMethod() {
        System.out.println("Executing anotherMethod");
    }
}

이제 myMethod가 실행될 때마다 @Logging Annotation의 value 속성 값이 로그로 남고, 해당 메서드 실행 전 logBefore 메서드가 실행됩니다.


5. 전체 흐름 정리

  1. Custom Annotation 정의: @Logging이라는 Annotation을 생성하여 메서드에 적용.
  2. AOP Aspect 정의: LoggingAspect 클래스를 작성하여, @Logging Annotation이 붙은 메서드 실행 시 자동으로 로그를 남기도록 설정.
  3. Annotation 적용: MyService 클래스에서 메서드에 @Logging을 적용하여, 해당 메서드가 실행될 때마다 로그를 자동으로 기록.

6. 결론

Spring AOP는 cross-cutting concerns(로깅, 보안, 트랜잭션 등)을 핵심 비즈니스 로직과 분리하여 구현할 수 있도록 해줍니다. Custom Annotation을 활용하면, 원하는 동작을 특정 메서드에 적용할 수 있으며, 코드 중복을 줄이고 유지보수성을 높이는 데 유용합니다.

이번 글에서는 **@Logging**이라는 Custom Annotation을 만들어, Spring AOP와 결합하여 메서드 실행 시 로그를 자동으로 기록하는 방법을 알아보았습니다. 이 방식은 로깅, 트랜잭션 처리, 권한 체크 등 여러 가지 부가기능을 구현할 때 유용하게 사용될 수 있습니다.

반응형