본문 바로가기

수업 & 공부

AOP (Aspect Oriented Programming)

AOP (관점 지향 프로그래밍) 란?

  • 흩어진 Aspect를 모듈화 할 수 있는 프로그래밍 기법
  • Aspect를 통해 위 공통 로직들을 모듈화 하고 어디에서 사용할지 정의및 관리한다
  • 반복되거나 중복되는 부분들을 분리하여 각 관점(Aspect) 을 기준으로 모듈화
  • (즉 AOP : Aspect로 모듈화하고 핵심 비지니스 로직에서 분리하여 재사용 한다)

https://zzang9ha.tistory.com/389

흩어져 있는 부분을 aspect로 모듈화 시킨 것. 그리고 모듈화 시킨 Aspect를  클래스에 어느 곳에 사용해야 하는지만 정의해주면 된다

 

 

AOP 주요 용어

  • Aspect : 흩어진 관심사를 모듈화 한 것 (AOP의 기본 모듈)
  • Advice : 실질적으로 어떤 일을 할 지 정의한 것 (구현체)
  • Pointcut : 어디에 적용해야 하는지 정의한 것
  • Target : Aspect의 적용 대상을 정의한 것
  • Join Point  : Advice 적용 있는 위치. (Spring AOP에서는 method join point 제공)

 

 


 

Sample

1. 스프링 부트 AOP 의존성 추가

// https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-aop', version: '2.7.4'

 

 

2. AOP

import com.example.SeungYeob.common.annotation.LogAspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;


@Aspect
@Component
public class ParameterAop {

    Logger logger = LoggerFactory.getLogger(LogAspect.class);

    @Before(value = "execution(* com.example.SeungYeob.user.controller..*.*(..))")
    public void before(JoinPoint joinPoint){
        logger.info("--------------- @Before ---------------");


        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method = methodSignature.getMethod();
        logger.info("method: " + method.getName());

        Object[] args = joinPoint.getArgs();
        for (Object arg : args){
            logger.info("type : " + arg.getClass().getSimpleName());
            logger.info("value: " + arg);
        }
    }

    @AfterReturning(value = "execution(* com.example.SeungYeob.user.controller..*.*(..))", returning = "object")
    public void afterReturn(JoinPoint joinPoint, Object object){
        logger.info("--------------- @After ---------------");
        logger.info(String.valueOf(object));
    }
}

 

Get매핑으로 userFindByMid 호출시 결과

 

 

2. AOP 어노테이션으로 특정 메소드 적용

(stopwatch로 메소드 실행시간 측정하기)

 

1. annotation

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

2. Aspect

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

@Component
@Aspect
public class LogAspect {
    Logger logger = LoggerFactory.getLogger(LogAspect.class);

    @Around("@annotation(LogExecutionTime)")
    public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();

        Object proceed = joinPoint.proceed();

        stopWatch.stop();
        logger.info(stopWatch.prettyPrint());

        return proceed;
    }
}

around Advice 메소드는 다음과 같은 형태를 띤다. 

 

여기서 첫번째 예제의 @Before @After은 메서드 실행 전과 후에 사용하는 공통 로직을 나눈 것 이고 

두번째 예제의 @Around 는  메서드 실행 전/후에 같은 공통 로직을 사용하고 싶을때 사용한다.

 

@Around("@annotation(LogExecutionTime)")

위 부분처럼 정의하면 LogExcutionTime 어노테이션을 사용했을때 적용이 된다

@Around(value = "execution(* com.example.SeungYeob.user.controller..*.*(..))")

위 부분은 어디 하위의 메소드들이 해당 AOP를 적용받을지 지정한 것이다

 

Object proceed = joinPoint.proceed

여기서 비지니스 메소드로 진행하도록(proceed) 하는 메소드가 proceed() 메소드이다. 

이 메소드가 실행되기 전이 첫번재 예제의 (@Before) 부분이고

메소드 실행 후가 (@After) 부분이라 생각하자

즉 proceed()가 호출 되기 전에는 비지니스 메소드 호출 전이고 

proceed()가 호출된 후에는 비지니스 메소드 호출 후라고 생각하면 된다.

 

어노테이션 인터페이스와 aspect는 같은 위치에 생성하자

 

위에서 정의한 LogExcutionTime 어노테이션을 사용하여 해당 메소드 실행시간을 측정한다

fibonacci api를 호출하면 아래와 같이 해당 메소드의 실행시간이 측정된다

 

 

 

 


 

Spring AOP 스프링이 해줄건데 너가 왜 어려워 해? Spring boot에서 aop logging 사용법 제일 쉽게 알려드

Spring AOP (Aspect Oriented Programming) - AOP는 관점 지향 프로그래밍으로 "기능을 핵심 비즈니스 기능과 공통 기능으로 '구분'하고, 공통 기능을 개발자의 코드 밖에서 필요한 시점에 적용하는 프로그래

jeong-pro.tistory.com

 

AOP around의 proceed() 메소드 동작에 대한 개념 정리

AOP around의 proceed() 메소드 동작에 대한 개념 정리 AOP에서 Advice 메소드의 동작 시점(동작 방식)에는 ㆍbefore : 비지니스 메소드 실행 전에 Advice 메소드 실행 ㆍafter-returning : 비지니스 메소드가 성공

developer-joe.tistory.com

 

'수업 & 공부' 카테고리의 다른 글

Filter, Interceptor, AOP  (0) 2022.11.04
프록시 패턴 (Proxy Pattern) @Transactional  (0) 2022.11.04
docker - zookeeper - KAFKA 참고 (KAFKA CLI)  (0) 2022.10.12
KAFKA  (0) 2022.10.07
Stream  (0) 2022.10.03