AOP # 용어 정리

심야·2022년 11월 24일
0

웹 개발

목록 보기
28/46

스프링 AOP는 5가지 용어가 있다. 5가지 용어를 정리해보자.

용어의미
Aspect관점, 측면, 양상
Advisor조언자, 고문
Advice조언, 충고
JoinPoint결합점
Pointcut자르는 점

Pointcut - Aspect 적용 위치 지정자

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

@Aspect
public class MyAspect {
    // @Before("execution(public void aop002.Boy.runSomething())")
    @Before("execution(* runSomething())")
    public void before(JoinPoint joinpoint){
        System.out.println("얼굴 인식 확인: 문을 개방하라");
        // System.out.println("열쇠로 문을 열고 집에 들어간다.");
    }
}

* runSomething() 이 코드가 Pointcut이다. @Before("execution(* runSomething())") 이 코드의 의미는 다음과 같다. 지금 선언하고 있는 메서드(public void before)를 (* runSomething) 메서드가 실행되기 전 (@Before)에 실행하라는 의미이다. 따라서 before(JoinPoint joinpoint)메서드가 실행되어 "얼굴 인식 확인: 문을 개방하라" 문자열이 출력된 후 @Before("execution(* runSomething())") 메서드의 "컴퓨터로 게임을 한다." 문자열이 출력되는 것이다. 여기서 public void before는 횡단 관심사를 실행하는 메서드이다.

그래서 Pointcut은 횡단 관심사를 적용할 타깃 메서드를 선택하는 지시자이다. Pointcut은 정규식과 Aspect 표현식 등을 사용할 수 있다.

사용 예시

[접근제한자패턴] 리턴타입패턴 [패키지&클래스패턴.]메서드이름패턴(파라미터패턴)[throws예외패턴]

리턴타입패턴과 메서드이름패턴(파라미터패턴)을 제외한 패턴은 생략 가능하다.

앞서 사용한 Pointcut의 의미를 살펴보겠다.

코드내용
public void aop002.Boy.runSomething()접근제한자는 public이고 리턴 타입은 void, aop002 패키지에 Boy 클래스 안에 파라미터가 없으며 던져지는 에러 상관없이 이름이 runSomething 메서드를 Pointcut으로 지정한다.
* runSomething()접근제한자, 리턴타입 상관없이 모든 패키지에서 모든 클래스 안에 파라미터가 없으며 던져지는 에러 상관없이 이름이 runSomething 메서드를 Pointcut으로 지정한다.

JoinPoint - 연결 가능한 지점

Pointcut은 JoinPoint의 부분 집합이고 스프링 AOP는 인터페이스를 기반한다. 그리고 스프링 AOP는 메서드에만 적용 가능하다. 그렇다면 JointPoint는 무엇일까?

JoinPoint는 "Pointcut 후보가 되는 모든 메서드들이 JointPoint, 즉 Aspect 적용이 가능한 모든 지점"이다. 그래서 Aspect를 적용할 수 있는 지점 중 일부가 Pointcut이 된다. 스프링 AOP에서 넓은 의미의 JoinPoint란 스프링 프레임워크가 관리하는 빈의 모든 메서드에 해당한다.

좁은 의미의 JoinPoint는 호출된 객체의 메서드다. 코드로 확인해보자

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

@Aspect
public class MyAspect {
    // @Before("execution(public void aop002.Boy.runSomething())")
    @Before("execution(* runSomething())")
    public void before(JoinPoint joinpoint){
        System.out.println("얼굴 인식 확인: 문을 개방하라");
        // System.out.println("열쇠로 문을 열고 집에 들어간다.");
    }
}

JoinPoint joinpoint 이 코드가 의미하는 것은 무엇일까?
romeo.runSomething() 메서드를 호출한 상태라면 JoinPoint는 romeo 객체의 runSomething() 메서드가 된다. 그런데 juliet.runSomething() 메서드를 호출한 상태라면 juliet 객체의 runSomething() 메서드가 된다. 결론적으로 JoinPint 파라미터를 이용해 알 수 있는 것은 아래와 같다.

  • 실행 시점에 호출된 메서드가 무엇인지
  • 실제 호출된 메서드를 소유한 객체가 무엇인지
  • 호출된 메서드 파라미터는 무엇인지

Advice - 언제, 무엇을

Advice는 Pointcut에 언제, 무엇을 적용할지 정의한 메서드다.

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

@Aspect
public class MyAspect {
    // @Before("execution(public void aop002.Boy.runSomething())")
    @Before("execution(* runSomething())")
    public void before(JoinPoint joinpoint){
        System.out.println("얼굴 인식 확인: 문을 개방하라");
        // System.out.println("열쇠로 문을 열고 집에 들어간다.");
    }
}

지정된 Pointcut 즉, * runSomething() 메서드가 시작되기 전(@Before)에 public void before() 메서드를 실행하라는 의미다.

Aspect - Advisor의 집합체

AOP에서 Aspect는 여러 개의 Advice와 여러 개의 Pointcut의 결합체이다. Advice는 [언제, 무엇을] 이란 의미를, Pointcut은 [어디에] 라는 의미를 내포한다. 그래서 Aspect는 [언제, 어디에, 무엇을] 이란 의미를 가진다.

```java
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.JoinPoint;

@Aspect
public class MyAspect {
    // @Before("execution(public void aop002.Boy.runSomething())")
    @Before("execution(* runSomething())")
    public void before(JoinPoint joinpoint){
        System.out.println("얼굴 인식 확인: 문을 개방하라");
        // System.out.println("열쇠로 문을 열고 집에 들어간다.");
    }
}

MyAspect 코드를 해석하면 Pointcut인 * runSomething() 메서드가 실행되기 전에 before() 메서드를 실행하라는 의미이다.

Advisor - 어디서, 언제, 무엇을

Aspect는 Advisor의 집합체라 하였다. 그럼 Advisor는 무엇일까?

Advisor는 한 개의 Advice와 한 개의 Pointcut의 결합체이다. 그런데 Advisor는 스프링 AOP에서만 사용하며 다른 AOP 프레임워크에서는 사용하지 않는다. 또 스프링 버전이 올라가 이제는 쓰지 말라고 권고하는 기능이다. 스프링이 발전해 지금은 다수의 Advice와 다수의 Pointcout을 조합하는 Aspect가 나왔기 때문에 하나의 Advice와 하나의 Pointcut만을 결합하는 Advisor를 사용할 필요가 없어졌다.

출처

스프링 입문을 위한 자바 객체지향의 원리와 이해

profile
하루하루 성실하게, 인생 전체는 되는대로.

0개의 댓글