AOP(Aspect-Oriented Programming)

CREE·2023년 9월 4일
0

Spring

목록 보기
3/4
post-thumbnail

정의

Aspect-Oriented Programming
AOP는 관점(Aspect)지향 프로그래밍으로, 관점을 기준으로 다양한 기능을 분리하여 보는 프로그래밍이다. 관점(Aspect)이란, 부가 기능과 그 적용처를 정의하고 합쳐서 모듈로 만든 것이다

즉 어떠한 로직을 핵심적인 관점, 부가적인 관점으로 나누어 보고, 그 관점을 기준으로 나누어 모듈화 하는것이다.


흩어진 관심사

Crosscutting Concerns

코드를 짜다보면 소스코드상에서 각각 다른 곳에서 반복적으로 쓰이는 똑같은 코드들을 발견하게 된다. 이것을 흩어진 관심사 라고 부른다.

이 흩어진 관심사들을 모듈화 하고 비즈니스 모델에서 분리해내서 재사용하는것이 AOP의 취지이다.


모듈화

반복되는 코드를 묶어 재사용한다.

코드의 반복을 줄이기 위해 공통되는 기능이나 컨샙을 묶어 재사용하게 된다.


주요 용어

  • Aspect: 흩어진 관심사를 모듈화 한 것. 주로 부가 기능을 모듈화
  • Target: Aspect을 적용하는 곳 ( 클래스나 메소드 )
  • Adivce: 실직적으로 어떤 일을 해야할 지에 대한 것, 실질적인 부가기능을 담은 구현체
  • JointPoint : Advice가 적용될 위치, 끼어들 수 있는 지점, 메서드 진입 지점, 생성자 호출 시점, 필드에서 값을 꺼내올 때 등 다양한 시점에서 적용가능
  • PointCut : JointPoint의 상세한 스펙을 정의한 것. 'A란 메서드의 진입 시점에 호출할 것'과 같이 더욱 구체적으로 Advice가 실행될 지점을 정할 수 있음.

Spring AOP

  • 스프링에서 제공하는 스프링 AOP는 프락시 기반의 AOP 구현체이다.
  • 프록시 객체를 사용하는 것은 접근 제어 및 부가 기능을 추가하기 위해서이다.
  • 스프링 AOP는 스프링 Bean에만 적용할 수 있다.
  • 모든 AOP 기능을 제공하는 것이 목적이 아닌, 중복 코드, 프록시 클래스 작성의 번거로움 등 흔한 문제를 해결하기 위한 솔루션을 제공하는 것이 목적이다.
  • 스프링 AOP는 순수 자바로 구현되었기 때문에 특별한 컴파일 과정이 필요하지 않다.

주요 어노테이션

  • @Aspect : 해당 클래스를 Aspect로 사용하겠다는 것을 명시합니다.
  • @Before : 대상 “메서드”가 실행되기 전에 Advice를 실행합니다.
  • @AfterReturning : 대상 “메서드”가 정상적으로 실행되고 반환된 후에 Advice를 실행합니다.
  • @AfterThrowing : 대상 “메서드에서 예외가 발생”했을 때 Advice를 실행합니다.
  • @After : 대상 “메서드”가 실행된 후에 Advice를 실행합니다.
  • @Around : 대상 “메서드” 실행 전, 후 또는 예외 발생 시에 Advice를 실행합니다.

사용법

  1. 의존성 추가

maven

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

gradle

implementation 'org.springframework.boot:spring-boot-starter-aop'
  1. 원하는 class에 @Aspect 어노테이션 추가
@Component
@Aspect
public class PerfAspect {

    @Around("execution(* com.example..*.EventService.*(..))")
    public Object logPerf(ProceedingJoinPoint pjp) throws Throwable {
        long begin = System.currentTimeMillis();
        Object reVal = pjp.proceed();
        System.out.println(System.currentTimeMillis() - begin);
        return reVal;
    }
}

@Around의 excution에서 적용하고자 하는 범위를 지정할수 있다.

excution이 아닌 annotation을 사용하면 해당 어노테이션이 있는 곳에서만 실행시킬수 있다.

profile
이리저리 컴공과

0개의 댓글