skip to content

Supported Designators in Spring AOP

Spring AOP matches only method-execution join points, so call, get, set and initialization designators simply never fire. Interviewers ask this to see whether you know the boundary before you promise field-level interception.

part ofSpring Frameworkoverview, primer and where to startread it →
on this pageshow

questions

4

In Spring AOP, what kind of join points can your aspects actually advise?

level: juniorimportance: must knowfreq 68%

answer

  1. Only method execution
  2. Proxy intercepts calls, not fields
  3. No get/set/constructor/static-init
  4. Self-invocation bypasses proxy
  5. Need more -> full AspectJ

basics

~10 s

Only method executions. Spring AOP wraps beans in proxies, so an aspect can run before/after/around a public method call on a Spring bean — but not field reads/writes, constructors, or static blocks.

solid answer

~40 s

Spring AOP is proxy-based, so the only join point it exposes is method execution on a Spring-managed bean. A join point is a point in program flow where an aspect can act; in Spring that point is always 'a proxied bean method is being executed.' You can advise those with @Before, @After, @AfterReturning, @AfterThrowing, and @Around. Field access (get/set), object construction, and static initializers are NOT join points here because a proxy can only intercept method calls that pass through it. This is a deliberate subset of AspectJ's much larger join-point model. If you genuinely need to intercept field access or constructors, you must switch to full AspectJ weaving; Spring AOP alone cannot do it.

code

java · 14 lines
java
@Aspect
@Component
public class AuditAspect {

    // WORKS: method execution join point on a Spring bean
    @Before("execution(* com.acme.OrderService.place(..))")
    public void beforePlace() {
        System.out.println("about to place order");
    }

    // Field reads/writes, constructors, and static blocks
    // simply have NO join point in Spring AOP — you cannot
    // write a pointcut that intercepts them here.
}

go deeper

for a junior

Know the headline: Spring AOP only advises method executions on beans.

for a middle

Explain it's because of proxies and name the self-invocation gotcha.

for a senior

Connect JDK vs CGLIB proxying to which methods are advisable and why fields/constructors aren't.

for a principal

Discuss when the method-only limit forces a move to AspectJ load-time/compile-time weaving and its trade-offs.

## The core fact Spring AOP supports **exactly one kind of join point: method execution** on a Spring-managed bean. ### Vocabulary (defined) - **Join point**: a point during program execution where an aspect could be applied. AspectJ defines many (method call, method execution, field get, field set, constructor call/execution, static initializer, exception handler, etc.). - **Pointcut**: an expression that *selects* a set of join points. - **Advice**: the code that runs at a matched join point (`@Before`, `@After`, `@AfterReturning`, `@AfterThrowing`, `@Around`). - **Aspect**: a class (annotated `@Aspect`) bundling pointcuts + advice. ### Why only method execution? Spring AOP is **proxy-based**. When a bean matches a pointcut, Spring wraps it in a proxy — a **JDK dynamic proxy** (if the bean implements interfaces) or a **CGLIB subclass proxy** (otherwise). Callers hold a reference to the proxy, not the raw object. The proxy can only do one thing: intercept **method invocations** that pass through it, then delegate to the real target. There is no mechanism to intercept a field read, a `new` call, or a static initializer, because those never route through the proxy. ### Practical consequences 1. **Field access is invisible.** Reading or writing `someBean.count` is a plain JVM field operation; no proxy sees it. 2. **Constructors are invisible.** The proxy is created *around* an already-constructed target, so the target's constructor has already run before any advice could apply. 3. **Self-invocation is invisible.** If a bean method calls `this.other()` internally, the call goes to the raw object, bypassing the proxy — so `other()`'s advice does NOT fire. This is the single most common AOP surprise. ### When you need more If you truly need field, constructor, or call-site interception, move to **full AspectJ** via load-time weaving (`@EnableLoadTimeWeaving` + a Java agent) or compile-time weaving (`aspectj-maven-plugin`). That weaves advice into bytecode and supports the entire join-point model. ### Rule of thumb For 95% of enterprise needs — transactions, security checks, logging, metrics, caching — method execution is all you need, which is exactly why Spring AOP picked this subset.

  • Why doesn't advice fire when a bean calls its own annotated method internally?
    Self-invocation (`this.method()`) goes straight to the raw target object and never passes through the proxy, so no interception happens. Workarounds: inject a self-reference, use AopContext.currentProxy(), or switch to AspectJ weaving.
  • Can Spring AOP advise a private method?
    No. Proxies can only intercept externally-invoked, overridable methods. JDK proxies see interface methods; CGLIB overrides non-final public/protected methods. Private methods aren't proxied, so they can't be advised.

saying these in an interview costs you the question

  • Claiming Spring AOP can intercept field reads/writes
  • Thinking constructors can be advised in Spring AOP
  • Believing internal self-calls are advised

context

open as a page

What happens if you write a Spring AOP pointcut using an AspectJ designator like call(), get(), or set()?

level: middleimportance: must knowfreq 55%

basics

~20 s

Spring rejects it at startup. Using an unsupported designator (call, get, set, initialization, etc.) throws IllegalArgumentException — it is NOT silently ignored. Only Spring's supported subset (execution, within, this, target, args, @annotation, bean, ...) is allowed.

open as a page

Explain why Spring AOP supports execution() but not call(), and what that means for intercepting a method invocation.

level: seniorimportance: should knowfreq 40%

basics

~20 s

call() matches at the caller's side; execution() matches where the method actually runs (callee side). Spring's proxy sits in front of the target, so it can only observe the execution. There's no caller-side hook, hence no call().

open as a page

A requirement needs you to intercept field writes and constructor calls across your codebase. How does Spring AOP's supported-designator subset constrain you, and what's the correct architectural move?

level: principalimportance: should knowfreq 22%

basics

~20 s

Spring AOP can't do it — it only advises method executions, so get/set (fields) and constructor join points aren't available. The move is to adopt full AspectJ via load-time or compile-time weaving, which supports the entire join-point model.

open as a page