https://sundaland.tistory.com/87
[ ▶ @AspectJ ]
@AspectJ는 어노테이션을 사용하여 일반적인 자바 클래스로 어드바이스를 선언하는 스타일을 의미한다. @AspectJ 스타일은 AspectJ 5 릴리스의 일환으로 AspectJ 프로젝트에서 도입되었다. 스프링은 포인트컷을 해석하고 매칭 (연결)하기 위해 AspectJ에서 제공하는 라이브러리를 사용하여 동일한 어노테이션을 AspectJ 5처럼 해석한다. 그러나 AOP 런타임은 여전히 순수한 스프링 AOP로 동작하여, AspectJ 컴파일러나 위버 (weaver)에 대한 의존성은 없다.
AspectJ 컴파일러와 위버를 사용하면 전체 AspectJ 언어를 사용할 수 있다.
@ AspectJ라는 어노테이션은 스프링이나 AspectJ 프레임워크 자체에 존재하지 않는다. 대신 AspectJ 라는 용어는 스프링 AOP 모듈에 비해 더 강력하고 고급 AOP 기능을 제공하는 AOP 프레임워크를 의미한다.
[ ▷ AspectJ Vs 스프링 AOP ]
- AspectJ: AspectJ는 컴파일 시, 컴파일 후 (바이너리 위빙), 그리고 타임 위빙을 제공하는 완전환 AOP 프레임워크로, 애스펙트를 정의하고 적용하는데 있어 광범위한 기능을 제공한다. AspectJ는 스프링 빈뿐만이 아니라 모든 자바 객체에 애스펙트를 적용할 수 있다.
- 스프링 AOP: 스프링 AOP는 스프링 프레임워크의 일부로, 프록시 기반 AOP 프레임워크이다. AspectJ의 기능 중 일부를 제공하며, 주로 스프링에서 관리되는 빈의 메서드 수준에서 인터셉션에 제한된다.
[ ▷ @AspectJ 스타일 ]
AspectJ 스타일은 일반적으로 스프링 내에서 액스펙트를 정의하기 위해 AspectJ 어노테이션을 사용하는 것을 의미한다. 스프링은 @Aspect, @Before, @After 등과 같은 AspectJ 스타일 어노테이션을 지원하며, 이들은 org.aspectj.lang.annotation 패키지에 속한다.
이 스타일은 XML 구성 대신 어노테이션을 사용하여 애스펙트를 작성할 수 있게 하여 더 선언적이고 간결하게 만든다.
[ ▷ AspectJ의 주요 어노테이션 (스프링 AOP에서 사용) ]
- @ AspectJ: 클래스를 애스펙트로 표시한다.
- @Before: 특정 메서드가 실행되기 전에 실행될 어드바이스를 정의한다.
- @After: 메서드의 실행 결과에 상관없이, 특정 메서드 실행 후에 실행될 어드바이스를 정의한다.
- @Around: 메서드 실행을 감싸는 어드바이스를 정의하여 실행 과정을 제어할 수 있게 한다.
- @AfterReturning: 메서드가 성공적으로 반환된 후에 실행될 어드바이스를 정의한다.
- @AtferThrowing: 메서드가 예외를 던질 때 실행될 어드바이스를 정의한다.
- @Pointcut: 재사용 가능한 포인트컷을 정의한다.
@ AspectJ라는 어노테이션은 존재하지 않지만, AspectJ 어노테이션은 스프링 AOP 내에서 애스펙트를 정의하는데 광범위하게 사용된다. 이러한 접근 방식은 스프링 문서에서 AspectJ 스타일 어노테이션 또는 AspectJ 문법으로 자주 언급된다.
[ ▷ Enabling @AspectJ Support ]
@AspectJ aspect를 기반으로 스프링 AOP를 구성하고, 이 애스펙트에 의해 어드바이스되는지 여부에 따라 빈을 auto-proxying 하는 스프링 지원 기능을 활성화해야 한다.
auto-proxying는 스프링인 특정 빈이 하나 이상의 애스펙트에 의해 어드바이스된다고 판단할 경우, 해당 빈에 대해 메서드 호출을 가로채고 필요한 경우 어드바이스를 실행할 수 있도록 자동으로 프록시를 생성하는 것을 의미한다.
@AspectJ 지원은 XML 또는 자바 기반 구성으로 활성화할 수 있다. 두 경우 모두 애플리케이션의 클래스패스에 AspectJ의 aspectjweaver.jar 라이브러리를 포함해야 한다. 이 라이브러리는 AspectJ 배포판의 lib 디렉토리나 Maven Central 저장소에서 사용할 수 있습니다
[ ▷ Java 기반 구성으로 @AspectJ 지원 활성화 ]
자바 @Configuration을 사용하여 @AspectJ 지원을 활성화하려면 @EnableAspectJAutoProxy 어노테이션을 추가한다.
@Configuration
@EnableAspectJAutoProxy
public class AppConfig {
}
[ ▷ XML 설정으로 @AspectJ 지원 활성화 ]
XML 기반 구성으로 @AspectJ 지원을 활성화하려면, <aop:aspectj-autoproxy> 요소를 사용한다.
<aop:aspectj-autoproxy/>
이는 XML 스키마 기반 설정에서 설명된 스키마 지원을 사용하는 것을 전제로 한다. aop 네임스페이스에서 태그를 가져오려면 AOP 스키마를 사용해야 한다.
[ ▷ Declaring an Aspect ]
@AspectJ 지원이 활성화된 상태에서, 애플리케이션 컨텍스트에 정의된 빈 중 클래스에 @AspectJ 어노테이션이 있는 @AspectJ 애스펙트는 스프링에 의해 자동으로 감지되며 스프링 AOP를 구성하는데 사용된다.
▼ 애플리케이션 컨텍스트에 있는 일반적인 빈 정의 @AspectJ 어노테이션이 있는 빈 클래스를 가리키는 방법
<bean id="myAspect" class="com.xyz.NotVeryUsefulAspect">
<!-- 여기에서 측면의 속성을 구성 -->
</bean>
▼ @AspectJ 어노테이션이 달린 NotVeryUsefulAspect 클래스 정의를 보여준다.
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class NotVeryUsefulAspect {
}
@AspectJ로 어노테이션된 Aspect 클래스는 다른 클래스와 마찬가지로 메서드와 필드를 가질 수 있으며, 포인트컷, 어드바이스, 그리고 인터타입 (Introduction) 선언을 포함할 수 있다.
[ ▷ Autodetecting aspects through component scanning ]
클래스패스 스캔을 통해 스프링인 애스펙트 클래스를 자동으로 감지하도록 하거나, 스프링 XML 설정에서 일반 빈으로 등록하거나, @Configuration 클래스의 @Bean 메서드를 통해 등록할 수 있다. 그러나 @Aspect 어노테이션만으로는 클래스패스에서 자동 감지가 충분하지 않다. 이 경우에는 @Component 어노테이션 (또는 스프링의 컴포넌트 스캐너 규칙에 따라 자격이 있는 사용자 정의 스트레오타입 어노테이션)을 추가해야 한다.
@Aspect
@Component
public class LoggingAspect {
}
@Configuration
@ComponentScan(basePackages = "패키지 위치")
public class AppConfig {
}
[ ▷ Advising aspects with other aspects? ]
스프링 AOP에서 애스펙트 자체는 다른 애스펙트의 어드바이스 대상이 될 수 없다. 클래스에 @Aspect 어노테이션이 붙으면 해당 클래스는 애스펙트로 표시되며, 따라서 auto-proxying 대상에서 제외된다.
[ ▷ Declaring a Pointcut ]
포인트컷은 관심 있는 조인 포인트를 결정하여 어드바이스가 실행될 시점을 제어할 수 있도록 한다. 스프링 AOP는 스프링 빈에 대한 메서드 실행 조인 포인트만 지원하므로, 포인트컷은 스프링 빈의 메서드 실행을 매칭하는 것으로 생각할 수 있다. 포인트컷은 스프링 빈의 메서드 실행을 매칭하는 것으로 생각할 수 있다. 포인트컷 선언은 이름과 파라미터를 포함하는 시그니처 (signature)와 관심 있는 메서드 실행을 정확히 결정하는 포인트컷 표현식으로 구성된다. @AspectJ 어느테이션 스타일의 AOP에서는 포인트컷 시그니처가 일반 메서드 정의에 의해 제공되며, 포인트컷 표현식은 @Pointcut 어노테이션을 사용하여 표시된다. (포인트컷 시그니처와 포인트컷 표현식 간의 차이를 명확히 하는데 도움이 될 것이다.
▼ transfer 메서드 실행을 매칭하는 anyOldTransfer 포인트컷을 정의한다.
@Pointcut("execution(* transfer(..))") // the pointcut expression
private void anyOldTransfer() {} // the pointcut signature
@Pointcut 어노테이션의 값으로 사용되는 포인트컷 표현식은 일반적인 AspectJ 포인트컷 표현식이다.
[ ▷ Supported Pointcut Designators(지시어) ]
스프링 AOP는 포인트컷 표현식에서 사용할 수 있는 다음과 같은 AspectJ 디지그네이터 (PCD)를 지원한다.
- execution: 메서드 실행 조인 포인트를 매칭한다. 스프링 AOP를 사용할 때 기본적으로 사용하는 포인트컷 디지그네이터이다.
- within: 특정 타입 내에서 조인 포인트를 제한한다. 스프링 AOP를 사용할 때 매칭되는 타입 내에서 선언된 메서드의 실행
- this: 빈 참조 (스프링 AOP 프록시)가 주어진 타입의 인스턴스인 경우 조인 포인트를 제한한다. 스프링 AOP를 사용할 때 메서드 실행
- target: 타겟 객체에 (프록시된 애플리케이션 객체)가 주어진 타입의 인스턴스인 경우 조인 포인트를 제한한다. 스프링 AOP를 사용할 때 메서드 실행
- args: 전달된 아규먼트가 주어진 타입의 인스턴스인 경우 조인 포인트를 제한한다. 스프링 AOP를 사용할 때 메서드 실행
- @target: 실행 중인 객체의 클래스에 주어진 타입의 어노테이션이 있는 경우 조인 포인트를 제한한다. 스프링 AOP를 사용할 때 메서드 실행
- @args: 런타임에 전달된 실제 아규먼트의 타입에 주어진 어노테이션이 있는 경우 조인 포인트를 제한한다. 스프링 AOP를 사용할 때 메서드 실행
- @witnin: 주어진 어노테이션이 있는 타입 내에서 조인 포인트를 제한한다. 스프링 AOP를 사용할 때 해당 어노테이션이 있는 타입에 선언된 메서드 실행
- @annotation: 조인 포인트의 대상 (스프링 AOP에서 실행 중인 메서드)에 주어진 어노테이션이 있는 경우 조인 포인트를 제한한다.
Other pointcunt types
전체 AspectJ 포인트컷 언어는 스프링에서 지원되지 않는 추가적인 포인트컷 디지그네이를 지원한다. 스프링 AOP가 해석하는 포인트컷 표현식에서 이러한 포인트컷 디지그네이터를 사용하면 IllegalArgumentException이 발생한다.
(call, get, set, preinitialization, staticinitialization, initialization, handler, adviceexecution, withincode, cflow, cflowbelow, if, @this, 그리고 @withincode)
스프링 AOP가 매칭을 메서드 실행 조인 포인트에만 제한하기 때문에, 위에서 설명한 포인트컷 디지그네이터의 정의는 AspectJ 프로그래밍 가이드에서 찾을 수 있는 정의보다 좁은 의미를 갖는다. 또한, AspectJ 자체는 type-base semantics를 가지고 있으며, 실행 조인 포인트에서 this와 target은 동일한 객체를 참조한다. (메서드를 실행하는 객체) 스프링 AOP는 프록시 기반 시스템으로, 프록시 객체 자체 (this에 바인딩됨)와 프록시 뒤의 타겟 객체 (taget에 바인딩됨)을 구분한다.
스프링의 AOP 프레임 워크는 프록시 기반이므로 타겍 객체 내의 호출은 정의상 가로채지 않는다. JDK 프록시의 경우, 프록시에 대한 public 인터페이스 메서드 호출만 가로챌 수 있다. CGLIB의 경우, 프록시에 대한 public 및 protected 메서드 호출이 가로채지며 (필요에 따라 package-visible 메서드도 가능하다) 하지만, 프록시를 통한 일반적인 상호 작용은 항상 public 시그니처를 통해 설계되어야 한다.
포인트컷 정의는 일반적으로 가로채진 메서드에 대해 매칭된다. 포인트컷이 public 메서드에만 해당되도록 하려면, CGLIB 프록시 시나리오에서 프록시를 통한 non-public 상호 작용 가능성이 있는 경우에도, 이에 맞게 정의해아 한다.
인터셉션이 타겟 클래스 내에서 메서드 호출이나 생성자를 포함해야 하는 경우, 스프링의 프록시 기반 AOP 프레임워크 대신 스프링 주도의 native AspectJ weaving을 사용하는 것을 고려한다. 이는 다른 특성을 가진 AOP 사용 모드를 구성하므로, 결정을 내리기 전에 위빙에 대해 충분히 이해하여야 한다.
스프링 AOP는 또한 bean이라는 추가 PCD를 지원한다. 이 PCD는 특정 의림의 스프링 빈이나 와일드카드를 사용하여 명명된 스프링 빈 세트에 대해 조인 포인트 매칭을 제한할 수 있다.
▼ bean PCD의 형태
bean(idOrNameOfBean)
idOrNameOfBean 토큰은 어떤 스프링 빈의 이름이라도 될 수 있다. 문자를 사용하는 제한된 와일드카드 지원이 제공되므로, 스프링 빈에 대한 명명 규칙을 설정하면 이를 선택하는 bean PCD 표현식을 작성할 수 있다. 다른 포인트컷 디지그네이터의 경우와 마찬가지로, bean PCD도 &&(and), ||(or) , !(부정) 연산자와 함께 사용할 수 있다.
bean PCD는 스프링 AOP에서만 지원되며, 네이티브 AspectJ 위빙에서는 지원되지 않는다. 이는 AspectJ가 정의한 표준 PCD에 대한 스프링 고유의 확장이므로 @ Aspect 모델로 선언된 측면에서는 사용할 수 없다.
bean PCD는 타입 수준에서만 작동하는 위빙 기반 AOP에 비해 인스턴스 수준에서 작동하며 (String 빈 이름 개념을 기반으로), 특정 빈을 이름으로 식별하는 것이 자연스럽고 직관적인 스프링 프록시 기반 AOP 프레임워크 및 스프링 빈 팩토리와의 긴밀한 통합의 특별한 기능이다.
[ ▷ Combining Pointcut Expressions ]
&&(and), ||(or) , !(부정) 연산자를 사용하여 포인트컷 표현식을 결합할 수 있다. 또한 포인트컷 표현식을 이름으로 참조할 수 있다.
public class Pointcuts {
@Pointcut("execution(public * *(..))")
public void publicMethod() {} 1
@Pointcut("within(com.xyz.trading..*)")
public void inTrading() {} 2
@Pointcut("publicMethod() && inTrading()")
public void tradingOperation() {} 3
}
- publicMethod는 메서드 실행 조인 포인트가 public 메서드 실행을 나타내는 경우 매칭된다.
- inTranding은 메서드 실행이 tranding 모듈 내에서 이루어진 경우 매칭된다.
- tradingOperation은 메서드 실행이 trading 모듈 내에서 수행되는 모든 public 메서드를 나타내는 경우 매칭된다.
위와 같이 더 복잡한 포인트컷 표현식을 더 작은 이름이 지정된 포인트컷으로 구성하는 것이 모범적이다. 포인트컷을 이름으로 참조할 때는 일반적인 자바 가시성 규칙이 적용된다. (동일한 타입에서 private 포인트컷을 볼 수 있으며, 상속 계층에서는 protected 포인트컷, 어디서나 public 포인트컷을 볼 수 있다.)
[ ▷ Sharing Named Pointcut Definitions ]
엔터프라이즈 애플리케이션을 작업할 때, 개발자들은 애플리케이션 모듈과 특정 작업 세트를 여러 애스펙트에서 참조해야 하는 경우가 종종 있다. 이 목적을 위해 자주 사용되는 이름이 지정된 포인트컷 표현식을 캡쳐하는 전용 클래스를 정의하는 것이 좋다. 이러한 클래스는 일반적으로 아래의 예시와 비슷하지만, 클래스 이름은 사용자에게 달려있다.
package com.xyz;
import org.aspectj.lang.annotation.Pointcut;
public class CommonPointcuts {
/**
* 메서드가 com.xyz.web 패키지 또는 하위 패키지에 정의된 타입에 있는 경우,
조인 포인트는 웹 레이어에 있습니다.
*/
@Pointcut("within(com.xyz.web..*)")
public void inWebLayer() {}
/**
* 메서드가 com.xyz.service 패키지 또는 하위 패키지에 정의된 타입에 있는 경우,
* 조인 포인트는 서비스 레이어에 있습니다.
*/
@Pointcut("within(com.xyz.service..*)")
public void inServiceLayer() {}
/**
* 메서드가 com.xyz.dao 패키지 또는 하위 패키지에 정의된 타입에 있는 경우,
* 조인 포인트는 데이터 액세스 레이어에 있습니다.
*/
@Pointcut("within(com.xyz.dao..*)")
public void inDataAccessLayer() {}
/**
* 비즈니스 서비스는 서비스 인터페이스에 정의된 모든 메서드의 실행입니다.
* 이 정의는 인터페이스가 "service" 패키지에 배치되고,
* 구현 타입이 하위 패키지에 있는 경우를 가정합니다.
*
* 기능별로 서비스 인터페이스를 그룹화하는 경우
* (예: com.xyz.abc.service 및 com.xyz.def.service 패키지에)
* "execution(* com.xyz..service.*.*(..))" 포인트컷 표현식을 대신 사용할 수 있습니다.
*
* 또는, 'bean' PCD를 사용하여 표현식을 작성할 수도 있습니다.
* 예: "bean(*Service)".
* (이 경우, Spring 서비스 빈의 이름이 일관되게 지정된다고 가정합니다.)
*/
@Pointcut("execution(* com.xyz..service.*.*(..))")
public void businessService() {}
/**
* 데이터 액세스 작업은 DAO 인터페이스에 정의된 모든 메서드의 실행입니다.
* 이 정의는 인터페이스가 "dao" 패키지에 배치되고,
* 구현 타입이 하위 패키지에 있는 경우를 가정합니다.
*/
@Pointcut("execution(* com.xyz.dao.*.*(..))")
public void dataAccessOperation() {}
}
이와 같은 클래스에 정의된 포인트컷을 참조하여 포인트컷 표현식이 필요한 곳 어디에서나 사용할 수 있다. 예를 들어, 서비스 레이어를 트랜잭션 처리 가능하게 만들려먼, 아래 예제와 같이 com.xyz.CommonPointcuts.businessService()라는 이름의 포인트컷을 참조하여 작성할 수 있다.
<aop:config>
<aop:advisor
pointcut="com.xyz.CommonPointcuts.businessService()"
advice-ref="tx-advice"/>
</aop:config>
<tx:advice id="tx-advice">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
[ ▷ Examples ]
스프링 AOP 사용자는 주로 execution 포인트컷 디지그네이터를 가장 자주 사용한다.
▼ execution 표현식의 형식
execution(modifiers-pattern?
ret-type-pattern
declaring-type-pattern?name-pattern(param-pattern)
throws-pattern?)
리턴 타입 패턴 (ret-type-pattern), 이름 패턴, 파라미터 패턴을 제외한 모든 부분은 선택 사항이다.
- 리턴 타입 패턴은 조인 포인트가 매칭되기 위해 메서드의 리턴 타입이 무엇이어야 하는지를 결정한다. * 은 가장 자주 사용되는 리턴 타입 패턴으로, 모든 리턴 타입을 매칭한다. 완전히 지정된 타입 이름은 메서드가 해당 타입을 리턴하는 경우에만 매칭된다.
- 이름 패턴은 메서드 이름을 매칭한다. * 와일드카드는 이름 패턴의 일부 또는 전체로 사용할 수 있다. 선언하는 타입 패튼을 지정하는 경우, 이름 패턴 구성 요소에 연결하기 위해 뒤에 . 을 포함해야 한다.
- 파라미터 패턴은 ()은 파라미터가 없는 메서드를 매칭하고, (..)은 임의의 수 (0개 이상)의 파라미터를 매칭한다.
- (*) 패턴은 하나의 파라미터를 가지는 메서드를 매칭하며, (*, String)은 두 개의 파라미터를 가지는 메서드를 매칭한다. 첫 번째는 임의의 타입일 수 있으며, 두 번째는 반드시 String이어야 한다.
▼ public 메서드의 실행
execution(public * *(..))
▼ 이름이 set으로 시작하는 모든 메서드의 실행
execution(* set*(..))
▼ AccountService 인터페이스에 정의된 모든 메서드의 실행
execution(* com.xyz.service.AccountService.*(..))
▼ service 패키지에 정의된 모든 메서드의 실행
execution(* com.xyz.service.*.*(..))
▼ service 패키지 또는 하위 패키지에 정의된 모든 메서드의 실행
execution(* com.xyz.service..*.*(..))
▼ service 패키지 내의 모든 조인 포인트 (오직 스프링 AOP에서 메서드 실행)
within(com.xyz.service.*)
▼ service 패키지 또는 하위 패키지 내의 모든 조인 포인트 (오직 스프링 AOP에서 메서드 실행)
within(com.xyz.service..*)
▼ 프록시가 AccountService 인터페이스를 구현하는 모든 조인 포인트 (오직 스프링 AOP에서 메서드 실행)
this(com.xyz.service.AccountService)
▼ 타겟 객체가 AccountService 인터페이스를 구현하는 모든 조인 포인트 (오직 스프링 AOP에서 메서드 실행)
target(com.xyz.service.AccountService)
▼ 런타임 시 전달된 인수가 Serializable 인스턴스인 모든 조인 포인트 (오직 스프링 AOP에서 메서드 실행)
args(java.io.Serializable)
▼ 타겟 객체에 @Transactional 어노테이션이 있는 모든 조인 포인트 (오직 스프링 AOP에서 메서드 실행)
@target(org.springframework.transaction.annotation.Transactional)
▼ 실행 중인 메서드에 @Transactional 어노테이션이 있는 모든 조인 포인트 (오직 스프링 AOP에서 메서드 실행)
@annotation(org.springframework.transaction.annotation.Transactional)
▼ 런타임 시 전달된 아규먼트 타입에 @Classified 어노테이션이 있는 모든 조인 포인트 (오직 스프링 AOP에서 메서드 실행)
@args(com.xyz.security.Classified)
▼ 이름이 tradeService인 스프링 빈에 대한 모든 조인 포인트 (오직 스프링 AOP에서 메서드 실행)
bean(tradeService)
▼ 이름이 *Service와 일치하는 스프링 빈에 대한 모든 조인 포인트 (오직 스프링 AOP에서 메서드 실행)
bean(*Service)
[ ▷ Writing Good Pointcuts ]
컴파일 과정에서 AspectJ는 모든 포인트컷을 처리하여 매칭 성능을 최적화한다. 코드를 분석하고 각 조인 포인트가 주어진 포인트컷과 일치하는지 (정적 또는 동적) 판단하는 것은 비용이 많이 드는 과정이다. (동적 매칭이랑 정적 분석만으로는 매칭을 완전히 결정할 수 없으며, 코드가 실행될 때 실제 매칭 여부를 판단하기 위한 테스트가 코드에 삽입된다는 의미이다.) 포인트컷 선언을 처음 접할 때, AspectJ는 이를 매칭 과정에 최적화된 형태로 제작성한다. 기본적으로 포인트컷은 DNF (Disjunctive Normal Form, 쌍대 논리 형식)로 재작성되며, 포인트컷의 구성 요소가 평가 비용이 저렴한 순서로 정렬된다. 이는 다양한 포인트컷 디지그네이터의 성능을 이해하지 안아도 포인트컷 선언에서 자유롭게 순서를 지정ㅇ할 수 있음을 의미한다.
그러나 AspectJ는 주어진 정보로만 작업할 수 있다. 최적의 매칭 성능을 위해서는 달성하고자 하는 목표를 고려하고, 정의에서 매칭을 위한 검색 범위를 가능한 좁히는 것이 좋다. 기존의 디지그네이터는 자연스럽게 세 가지 그룹으로 나뉜다.
- Kinded 디지그네이터: 특정 종류의 조인 포인트를 선택 (excutiom, get, set, call, hadler)
- Scoping 디지그네이터: 관심 있는 조인 포인트 그룹을 선택 (여러 종류)
- Contextual 디지그네이터: 문맥에 따라 매칭 및 선택적으로 바인딩한다. (this, target, @annotation)
잘 작성된 포인트컷은 최소한 앞의 두 가지 타입 (Kinded 지정과 Scoping 지정)을 포함해야 한다. contextual 지정을 포함하여 조인 포인트 컨텍스트에 따라 매칭하거나 그 컨텍스트를 어드바이스에서 사용할 수 있도록 바인딩할 수도 있다. Kinded 지정이나 Contextual 지정에만 제공하는 것도 작동하긴 하지만, 추가적인 처리와 분석 때문에 위빙 성능 (시간과 메모리 사용량)에 영향을 미칠 수 있다. Scoping 지정은 매칭 속도가 매우 빠르며, 이를 사용하면 AspectJ가 더 이상 처리하지 않아야 하는 조인 포인트 그룹을 매우 빠르게 제외할 수 있다. 가능한 Scoping 지정을 항상 포함하는 것이 좋다.