스프링 AOP의 다섯 가지 통지 유형

스프링 AOP에서 제공하는 핵심 기능 중 하나는 다양한 통지 유형을 통해 프로그램 실행 흐름을 제어하는 것입니다. 이 기능을 활용하면 비즈니스 로직과 분리된 공통 기능(예: 로깅, 트랜잭션 관리)을 효과적으로 구현할 수 있습니다.

CustomAnnotation.java

package com.example.aop;

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 CustomAnnotation {
}

ConfigSetup.java

package com.example.aop;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@Configuration
@ComponentScan
@EnableAspectJAutoProxy
public class ConfigSetup {
}

LoggingAspect.java

package com.example.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class LoggingAspect {
    // 실행 전 처리
    @Before("@annotation(CustomAnnotation)")
    public void preExecution(JoinPoint jp) {
        String methodName = jp.getSignature().getName();
        System.out.println(methodName + " 메서드 실행 시작");
    }

    // 실행 후 처리
    @After("@annotation(CustomAnnotation)")
    public void postExecution(JoinPoint jp) {
        String methodName = jp.getSignature().getName();
        System.out.println(methodName + " 메서드 실행 완료");
    }

    // 반환 시 처리
    @AfterReturning(value = "@annotation(CustomAnnotation)", returning = "result")
    public void onReturn(JoinPoint jp, Object result) {
        String methodName = jp.getSignature().getName();
        System.out.println(methodName + " 반환 값: " + result);
    }

    // 예외 발생 시 처리
    @AfterThrowing(value = "@annotation(CustomAnnotation)", throwing = "ex")
    public void onError(JoinPoint jp, Exception ex) {
        String methodName = jp.getSignature().getName();
        System.out.println(methodName + " 예외 발생: " + ex.getMessage());
    }

    // 전체 흐름 감싸기
    @Around("@annotation(CustomAnnotation)")
    public Object aroundAdvice(JoinPoint jp) throws Throwable {
        Object[] args = jp.getArgs();
        Object result = jp.proceed(args);
        return result;
    }
}

AppMain.java

package com.example.aop;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class AppMain {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConfigSetup.class);
        MathOperations math = context.getBean(MathOperations.class);
        math.calculate(3, 4);
        math.subtract(5, 2);
    }
}

MathOperations.java

package com.example.aop;

public interface MathOperations {
    int calculate(int x, int y);
    void subtract(int x, int y);
}

MathServiceImpl.java

package com.example.aop;

import org.springframework.stereotype.Component;

@Component
public class MathServiceImpl implements MathOperations {
    @CustomAnnotation
    public int calculate(int a, int b) {
        System.out.println(a + " + " + b + " = " + (a + b));
        return a + b;
    }

    @CustomAnnotation
    public void subtract(int a, int b) {
        System.out.println(a + " - " + b + " = " + (a - b));
    }
}

실행 결과:

calculate 메서드 실행 시작
3 + 4 = 7
calculate 반환 값: 7
calculate 메서드 실행 완료
subtract 메서드 실행 시작
5 - 2 = 3
subtract 메서드 실행 완료

태그: Spring AOP aspectj 애노테이션 기반 개발 프록시 패턴 관점 지향 프로그래밍

6월 29일 20:07에 게시됨