Spring - AOP

CYSSSSSSSSS·2024년 4월 21일
0

스프링

목록 보기
15/16

Spring

AOP

AOP?

  • Aspect Oriented Programming의 약자로 특정한 함수 호출 전이나 후에 공통적인 처리가 필요하다면 사용하는 기능이다.
  • AOP에는 로깅,트랜잭션,인증등이 있다.
  • 로깅은 특정 함수를 호출했지만 조금더 자세한 로깅을 하고 싶을때
  • 트랜잭션은 내부적으로 트랜잭션이 시작하는 부분과 끝나는 지점에서의 처리를 AOP가 대신 해주는 방식
  • 인증은 특정 영역에 대해서 추가적인 인증이 필요할때 AOP를 사용한다.
  • ex) 사용자가 하나의 리소스를 사용할때 락을 걸어서 중복 방지를 하고 싶을때
  • AOP를 쓸때 코드 분석이 어려워지는 문제점이 있다.

Aspect

  • 여러 클래스나 기능에서 공통적으로 AOP를 넣어줘야 하는 하나의 주제라고 생각하면 된다.
  • 스프링 프레임워크에서 해당 주제의 기능을 사용할때 AOP를 사용해야 한다.
  • 이런 것들을 넣어둔 하나의 큰 모듈이라고 생각하면 된다.

Advice

  • AOP에서 실제를 적용하는 기능들(로깅 , 트랜잭션 , 인증)

Join Point

  • 프로그램이 진행하고 있을때 클래스 생성,클래스 메소드 호출,리턴값,다음 메소드 호출등 일련의 프로그램 흐름들을 전부 AOP를 심을수는 없다.
  • 프로그램이 진행하는 동안 해당 Aspect를 넣어 줄 수 있는 포인트가 Join Point이다.

Pointcut

  • Aspect들이 특정 Join Point에 심어지게 되었을때 심어지는 포인트를 Pointcut이라고 한다.
  • JoinPoint에 Aspect가 심어질 특정 조건식이라고 생각하면 된다.

Target Object

  • Advice(로깅,트랜잭션,인증) 적용될 특정 Object를 말한다.

AOP Proxy

  • Object에 Aspect를 적용시키는 경우 Advice를 덧붙이기 위한 작업이다.
  • 주로 실시간으로 코드를 생성하는 라이브러리에서 Proxy를 사용하여 처리한다.

Weaving

  • Aspect에 Advice를 비즈니스 로직 코드에 삽입하는 과정을 Weaving이라고 한다.

AspectJ

  • AOP를 활용할때 주로 사용하는 라이브러리
  • 기본적으로 제공되는 SpringAOP 에서는 Pointcut등 AOP를 사용할 수 없음
  • Spring boot에 기본적으로 추가되어 있다.

Aspect 생성

package org.xyz;
import org.aspectj.lang.annotation.Aspect;

@Aspect
@Component  // Component를 붙인 것은 해당 Aspect를 스프링의 Bean으로 등록해서 사용하기 위함
public class UsefulAspect {

}
  • @Component로 빈을 등록을 해주고 + @Aspect 어노테이션을 붙이면 Pointcut과 Advice를 들고 있는 하나의 Aspect가 만들어 진다.

PointCut 선언

package org.xyz;
import org.aspectj.lang.annotation.Aspect;

@Aspect
@Component  // Component를 붙인 것은 해당 Aspect를 스프링의 Bean으로 등록해서 사용하기 위함
public class UsefulAspect {

	@Pointcut("execution(* transfer(..))")
	private void anyOldTransfer() {}
}
  • 해당 Aspect가 적용될 JoinPoint를 찾기 위한 패턴 또는 조건 생성
  • 포인트 컷에 표현식이라고 부르기도 함

PointCut 결합

package org.xyz;
import org.aspectj.lang.annotation.Aspect;

@Aspect
@Component  // Component를 붙인 것은 해당 Aspect를 스프링의 Bean으로 등록해서 사용하기 위함
public class UsefulAspect {

	@Pointcut("execution(public * *(..))")
	private void anyPublicOperation() {} //public 메서드 대상 포인트 컷

	@Pointcut("within(com.xyz.myapp.trading..*)")
	private void inTrading() {} // 특정 패키지 대상 포인트 컷

	@Pointcut("anyPublicOperation() && inTrading()")
	private void tradingOperation() {} // 위의 두 조건을 and(&&) 조건으로 결합한 포인트 컷
}
  • 특정 포인트컷 두개를 && 조건식을 통해 하나의 포인트 컷으로 결합도 가능하다.

Advice 정의

  • 포인트 컷들을 활용하여 전/후/주변에서 실행될 액션을 정의할 때 사용한다.

Before Advice

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class BeforeExample {
@Before("com.xyz.myapp.CommonPointcuts.dataAccessOperation()")
    public void doAccessCheck() {
        // ...
    }
}
  • 해당 Advice를 실행할 때 메소드를 이용하여 한번더 체크해보는 과정을 만든 것이다.
  • 예제는 dataAccessOperation이라는 메서드가 Advice를 실행하기 전에 doAccessCheck라는 메서드를 실행해서 인증하라는 예제이다.

After Returning Advice

  • 데이터를 return을 시킨 다음에 동작하는 advice이다
  • 주로 로깅에서 사용한다.
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterReturning;

@Aspect
public class AfterReturningExample {

  @AfterReturning("com.xyz.myapp.CommonPointcuts.dataAccessOperation()")
    public void doAccessCheck() {
        // ...
    }
}
  • dataAccessOperation이 마찬가지로 doAccessCheck라는 메소드를 실행시켜준다.

Around Advice

  • 어떤 비즈니스 로직을 만들었을때 전이나 후에 동작하는 Advice이다.
  • 주요기능을 사용할때 전과 후에 확인 가능하여 좋은 장점이 있다.
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.ProceedingJoinPoint;

@Aspect
public class AroundExample {

    @Around("com.xyz.myapp.CommonPointcuts.businessService()")
    public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
        // start stopwatch
        Object retVal = pjp.proceed();
        // stop stopwatch
        return retVal;
    }
}
  • businessService라는 포인트컷의 전과 후에 필요한 동작을 추가한다.
  • ProceedingJoinPoint라는 것은 지정된 포인트 컷에 위치를 의미한다.
  • 포인트 컷을 잡아둔 함수를 실행 시키는 구조이다.
profile
개발자 되고 싶어요

0개의 댓글