[← What Spring AOP is](01-what-spring-aop-is.md) · [Index](../README.md) · [Proxy types →](03-proxy-types.md) # 2. The designator reference Generated by [`DesignatorAspect`](../src/main/java/com/ankurm/aop/aspect/DesignatorAspect.java) and [`PointcutParserEndpoint`](../src/main/java/com/ankurm/aop/web/PointcutParserEndpoint.java). Transcript: [`01-designators.txt`](output/01-designators.txt). ## Supported | Designator | Matches on | Evaluated | Cost | |---|---|---|---| | `execution(...)` | method signature | statically | cheap | | `within(Type)` | the declaring type | statically | cheap | | `this(Type)` | the **proxy**'s type | at runtime | per call | | `target(Type)` | the **target object**'s type | at runtime | per call | | `args(Types)` | argument runtime types; can bind | at runtime | per call | | `@target(Ann)` | annotation on the executing object's class | at runtime | per call | | `@args(Ann)` | annotation on argument runtime types | at runtime | per call | | `@within(Ann)` | annotation on the declaring type | statically | cheap | | `@annotation(Ann)` | annotation on the method | statically | cheap | | `bean(name)` | Spring bean name, wildcards allowed | — | cheap | `bean(...)` is Spring's own; it does not exist in AspectJ. The runtime group cannot be decided from the signature alone, so Spring must check on every candidate invocation. Prefer the static equivalent where one exists: `@within` instead of `@target`, `within` instead of `this`, when the distinction does not matter. ## What each one actually matched here ``` execution (full signature) -> DefaultOrderService.place(..) execution (wildcards) -> DefaultOrderService.cancel(..) within -> InventoryService.reserve(..) this(OrderService) -> place, cancel, interfaceless target(DefaultOrderService) -> place, cancel, interfaceless args (bound: SKU-1/2) -> DefaultOrderService.place(..) @target(Audited) -> DefaultOrderService.cancel(..) @args(Trackable) -> DefaultOrderService.interfaceless(..) @within(Audited) -> DefaultOrderService.place(..) @annotation(Marker) -> DefaultOrderService.place(..) bean(inventoryService) -> InventoryService.reserve(..) bean(*OrderService) -> place, cancel, interfaceless ``` `InventoryService.finalCheck` was called and appears nowhere: it is `final`, so no proxy could override it. That is [failure 4](05-broken-aspect-gallery.md). ## Not supported `call`, `get`, `set`, `preinitialization`, `staticinitialization`, `initialization`, `handler`, `adviceexecution`, `withincode`, `cflow`, `cflowbelow`, `if`, `@this`, `@withincode`. All fourteen were fed to the parser. All fourteen were rejected, with: ``` org.aspectj.weaver.tools.UnsupportedPointcutPrimitiveException Pointcut expression 'call(* ...place(..))' contains unsupported pointcut primitive 'call' ``` **The reference documentation says these throw `IllegalArgumentException`. They do not.** `UnsupportedPointcutPrimitiveException extends RuntimeException` directly — checked with `javap`, pinned by `AopContractTests.unsupportedDesignatorExceptionType`. A `catch (IllegalArgumentException)` will not catch it. ## When the failure happens `setExpression(...)` only stores the string. The expression is not parsed or validated until something asks it to match. An unsupported designator therefore fails at the first candidate invocation, not at startup — so a rarely-exercised aspect can ship broken. ## Combining and naming `&&`, `||` and `!` compose designators. Name the result rather than repeating it: ```java @Pointcut("within(com.ankurm.aop.service..*)") public void inServiceLayer() {} @Before("this(OrderService) && inServiceLayer()") public void advice(JoinPoint jp) { } ``` A named pointcut is referenced by its method name and is the single biggest readability win available here.