[Section 2] Pointcut과 JoinPoint, Annotation

Kim·2022년 10월 18일
0

Boot Camp

목록 보기
32/64
post-thumbnail

Pointcut 표현식

포인트컷과 표현식, 지시자

포인트컷은 관심 조인 포인트를 결정한다. 어드바이스가 실행되는 시기를 제어할 수 있다.
AspectJ는 포인트컷을 편리하게 표현하기 위한 특별한 표현식을 제공한다.
@Pointcut("execution(* hello.aop.order..*(..))")

@Pointcut("execution(* transfer(..))") // 포인트컷 표현식
private void anyOldTransfer() {} // 포인트컷 서명

포인트컷 지시자

포인트컷 표현식은 execution 같은 포인트컷 지시자(Pointcut Designator, PCD)로 시작한다.
execution을 가장 많이 사용한다.

포인트컷 표현식 결합

포인트컷 표현식은 &&, ||, !를 사용해 결합할 수 있다. 이름으로 포인트컷 표현식을 참조할 수도 있다.

@Pointcut("execution(public * *(..))")
private void anyPublicOperation() {} // (1)

@Pointcut("within(com.xyz.myapp.trading..*)")
private void inTrading() {} // (2)

@Pointcut("anyPublicOperation() && inTrading()")
private void tradingOperation() {} // (3)
  1. anyPublicOperation은 메서드 실행 조인 포인트가 공용 메서드의 실행을 나타내는 경우 일치한다.

  2. in Trading 메서드 실행이 거래 모듈에 있는 경우에 일치한다.

  3. tradingOperation은 메서드 실행이 거래 모듈의 공개 메서드를 나타내는 경우 일치한다.


JoinPoint

AOP의 적용 위치

AOP는 메서드 실행 위치 뿐만 아니라 다양한 위치에 적용할 수 있다.
적용 가능 지점을 Join Point(조인 포인트)라 하고, 조인 포인트는 생성자와 필드 값 접근, static 메서드 접근, 메서드 실행 위치에 적용할 수 있다.
AOP를 수행하는 메소드는 Join Point 인스턴스를 인자로 받게 된다. 조인 포인트 인스턴스에서 조인 포인트 지점의 정보를 얻어내야 한다.

Join Point

조인 포인트는 추상적인 개념이며 AOP를 적용할 수 있는 지점을 의미한다.
AspectJ를 사용해 컴파일 시점과 클래스 로딩 시점에 적용하는 AOP는, 바이트코드를 실제 조작하기 때문에 해당 기능을 모든 지점에 다 적용할 수 있다.

프록시 방식을 사용하는 스프링 AOP는 메서드 실행 지점에만 AOP를 적용할 수 있다. 프록시는 메서드 오버라이딩 개념으로 동작한다. 생성자나 static 메서드, 필드 값 접근에는 프록시 개념이 적용될 수 없다.
프록시를 사용하는 스프링 AOP의 조인 포인트는 메서드 실행으로 제한되며, 스프링 컨테이너가 관리할 수 있는 스프링 빈에만 AOP를 적용할 수 있다.

JoinPoint 메소드는 어드바이스의 종류에 따라 사용방법이 다소 다르지만 기본적으로 어드바이스 메소드에 매개변수로 선언만 하면 된다.

JoinPoint 인터페이스의 주요 기능

  • JoinPoint.getArgs() : JoinPoint에 전달된 인자를 배열로 반환한다.

  • JoinPoint.getThis() : AOP 프록시 객체를 반환한다.

  • JoinPoint.getTarget() : AOP가 적용된 대상 객체를 반환한다.
    클라이언트가 호출한 비즈니스 메소드를 포함하는 비즈니스 객체를 반환한다.

  • JoinPoint.getSignature() : 조언되는 메서드에 대한 설명을 반환한다.

클라이언트가 호출한 메소드의 시그니처(리턴타입, 이름, 매개변수) 정보가 저장된 Signature 객체를 반환한다.

`Signature` : 객체가 선언하는 모든 연산은 연산의 이름, 매개변수로 받아들이는 객체들을 말한다.

<Signature가 제공하는 메서드>
String getName() : 클라이언트가 호출한 메소드의 이름을 반환한다.
String toLongString() : 클라리언트가 호출한 메소드의 리턴타입, 이름, 매개변수를 패키지 경로까지 포함해서 반환한다.
String toShortString() : 클라이언트가 호출한 메소드 시그니처를 축약한 문자열로 반환한다.
  • JoinPoint.toString() : 조언되는 방법에 대한 유용한 설명을 인쇄한다.

ProceedingJoinPoint 인터페이스의 주요 기능

  • proceed() : 다음 어드바이스나 타켓을 호출한다.

Annotation을 이용한 AOP

Spring에서의 AOP

AOP는 스프링 IoC를 보완해 매우 강력한 미들웨어 솔루션을 제공한다.

Spring AOP 지원

  • @AspectJ 애너테이션 스타일

  • 스키마 기반 접근

@AspectJ 지원

@AspectJ는 애너테이션이 있는 일반 Java 클래스로 관점을 선언하는 스타일이다.
AOP 런타임은 여전히 순수한 스프링 AOP이며, AspectJ 컴파일러나 위버에 의존하지 않는다.

@AspectJ 지원 활성화

Spring 설정에서 @AspectJ aspect를 사용하기 위해서는 @AspectJ aspect에 기반한 Spring AOP 설정과, 이러한 aspect에 의해 조언되는 자동 프록시 빈에 대한 Spring 지원을 활성화해야 한다.

@AspectJ 지원은 XML 또는 Java 스타일 설정으로 활성화할 수 있다.

Java 설정으로 @AspectJ 지원 활성화 하기
@Configuration으로 @AspectJ 지원을 활성화하려면 @EnableAspectJAutoProxy 애너테이션을 추가한다.

@Configuration
@EnableAspectJAutoProxy
public class AppConfig {

}

Aspect 선언

@AspectJ 지원이 활성화되면 @AspectJ 관점(@Aspect 애너테이션)이 있는 클래스로 애플리케이션 컨텍스트에 정의된 모든 빈이 Spring에서 자동으로 감지되고 Spring AOP를 구성하는 데 사용된다.

<bean id="myAspect" class="org.xyz.NotVeryUsefulAspect">
    <!-- configure properties of the aspect here -->
</bean>
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class NotVeryUsefulAspect {

}

Pointcut 선언

포인트컷은 관심 조인 포인트를 결정하므로 어드바이스가 실행되는 시기를 제어할 수 있다.
포인트컷 선언은 이름과 매개변수를 포함하는 서명과 관심 있는 메소드 실행을 정확히 결정하는 pointcut 표현식의 두 부분으로 구성된다.

  • pointcut 표현식 : @Pointcut 애너테이션을 사용하여 표시한다.

Advice 선언

어드바이스는 포인트컷 표현식과 연관된다. 포인트컷과 일치하는 메서드의 실행 전후에 실행된다.


참고 자료

0개의 댓글