본문 바로가기

AspectJ 포인트컷 표현식 작성하기

2021. 4. 13.

Spring AOP 와 비교표

  AspectJ Spring AOP
적용 대상 모든 객체 bean 객체
구현 복잡 간편
기능 강력 간단한 기능
성능 Spring에 비해 빠름 AspectJ에 비해 느림

AspectJ란

매서드 시그니처 패턴

일반 표현식 매칭

excution(* 패키지.클래스.*(..))
  • 앞쪽 와일드 카드 : 모든 수정자, 반환형 매칭
  • 뒤쪽 와일드 카드 : 모든 매서드 매칭
  • ( .. ) : 모든 인수 개수 매칭
excution(* 클래스명.*(..))
  • 대상 클래스나 인터페이스가 애스펙트와 같은 패키지에 있을 경우 패키지명 생략 가능
  1. public 매서드 지정 표현
    excution(public * className.*(..))
  2. 반환형 지정 표현
    excution(public double className.*(..))
  3. 인수 목록 제약 표현
    excution(public double className.*(double, ..))
  4. 인수형, 갯수 제약 표현
    excution(public * className.*(double, double))

Annotation 매칭

  • 매칭하고 싶은 매서들 사이의 공통 특성이 없을 경우 사용할 수 있다.
  1. annotaion 생성
  2. // 어노테이션을 부착할 수 있는 타입 설정 @Target({ElementType.METHOD, ElementType.TYPE}) // 어느 시점까지 annotation 메모리를 사용할지 설정 @Retention(RetentionPolicy.RUNTIME) // javadoc 및 같은 툴에 의해 디폴트로 문서화 되는 것을 나타냅니다. @Documented public @interface Logging { }
  3. 표현식
  4. @Logging public class ClassName { ... }

@Aspect
public class Classname {

@Pointcut("annotaion(패키지명.Logging)")
public void loggingOper() {}

}


### 타입 시그니처 패턴 표현

- 특정한 타입 내부의 모든 조인포인트를 매치

~~~java
//패키지 명의 전체 메서드 실행 조인포인트 매치
within(패키지명.*)

//패키지 명의 하위패키지도 같이 매치
within(패키지명..*)

//특정 클래스 내부에 구현된 메서드 실행 조인포인트 매치
// 해당 클래스의 패키지가 aspect와 같으면 패키지명 생략가능
within(패키지명.클래스명)

// 인터페이스를 구현한 모든 클래스의 메서드 실행 조인포인트 매치
within(인터페이스명+)

포인트컷 표현식 조합

  • && (and)
  • || (or)
  • ! (not)

예시

within(InterfaceName+) || within(InterfaceName+)

포인트컷 매개변수 선언

예시

@Aspect
public class CalculatorPointcuts {
    ...
    @Pointcut("execution(* *.*(..)) && target(target) && args(a,b)")
    public void parameter(Object target, double a, double b) {}
}
  • target()과 args()로 매개변수를 설정하고 매칭시킬수 있다.

Introduction을 이용해 POJO에 기능 더하기

introduction 이란?

  • AOP 어드바이스의 특별한 타입
  • 객체가 어떤 인터페이스의 구현 클래스를 공급받아 동적으로 인터페이스를 구현하는 기술
  • 객체가 런타임에 구현 클래스를 상속하는 것처럼 보임
  • 다중 상속 가능

동작 원리 : introduction은 동적 프록시에 여러 인터페이스를 지정해 작동

사용법

@Aspect
@Component
public class Exam {

    @DeclareParents(
    value = "패키지명.클래스명",
    defaultImpl = 구현클래스명.class
    )
    public Interface1 interface1;


    @DeclareParents(
    value = "패키지명.클래스명",
    defaultImpl = 구현클래스명.class
    )
    public Interface2 interface2;

}
  • 위와 같이 introduction을 만들고 사용할 클래스에서 빈 객체를 생성해 사용할 수 있다.

 

'스프링 5 레시피 > 스프링 코어' 카테고리의 다른 글

AOP + POJO  (0) 2021.04.14
AOP 지향 프로그래밍  (0) 2021.04.12
댓글