skip to content

What is Spring AOP and how does it apply an aspect to a bean at runtime?

level: juniorimportance: must knowfreq 70%

answer

  1. Proxy wraps the bean at runtime
  2. JDK (interface) vs CGLIB (subclass)
  3. Method-execution join points on beans only
  4. No build step, pure Java
  5. @Aspect syntax != AspectJ weaver

basics

~20 s

Spring AOP adds cross-cutting behavior (logging, transactions, security) by wrapping a Spring bean in a proxy. The proxy runs your advice before/after the real method call. It works only on Spring-managed beans and needs no extra build step.

solid answer

~40 s

Spring AOP is a proxy-based aspect framework. At startup Spring wraps each advised bean in a dynamic proxy: a JDK interface proxy if the bean has interfaces, or a CGLIB subclass proxy otherwise (Spring Boot defaults to CGLIB). Callers get the proxy, not the raw object; each call passes through the proxy, which runs the matching advice (an @Around/@Before/@After method on an @Aspect) and then delegates to the target. Because weaving happens by composition at runtime, there is no special compiler or agent — it is pure Java. The trade-off: it only intercepts external calls to public method-execution join points on Spring beans. It cannot advise fields, constructors, static methods, final classes/methods, or plain non-Spring objects, and self-invocation inside the same bean bypasses the proxy.

code

java · 20 lines
java
@Aspect
@Component
public class TimingAspect {

    // Pointcut: every method execution in a *Service bean
    @Around("execution(* com.acme..*Service.*(..))")
    public Object time(ProceedingJoinPoint pjp) throws Throwable {
        long start = System.nanoTime();
        try {
            return pjp.proceed();          // delegate to the real target method
        } finally {
            long micros = (System.nanoTime() - start) / 1_000;
            System.out.println(pjp.getSignature() + " took " + micros + "us");
        }
    }
}

@SpringBootApplication
@EnableAspectJAutoProxy   // implicit in Spring Boot; shown for clarity
public class App { }

go deeper

for a junior

Must know: aspect = reusable cross-cutting code; Spring wraps the bean in a proxy that runs advice around the method.

for a middle

Should articulate JDK vs CGLIB selection and that only bean method executions are join points.

for a senior

Explains the auto-proxy BeanPostProcessor, the annotation-syntax-vs-weaver distinction, and enumerates proxy limitations.

for a principal

Frames proxy weaving as a deliberate zero-friction default and knows exactly the boundary where it stops being sufficient.

## What AOP solves **Aspect-Oriented Programming (AOP)** factors out *cross-cutting concerns* — behavior that would otherwise be scattered across many methods (logging, metrics, `@Transactional`, `@PreAuthorize` security, caching, retry). Instead of copy-pasting that code, you write it once in an **aspect** and declare *where* it applies with a **pointcut**. ### Core vocabulary (all define-once terms) - **Join point**: a point in program execution where an aspect *can* run. In Spring AOP this is always a **method execution** on a Spring bean — nothing else. - **Pointcut**: an expression selecting which join points to advise, e.g. `execution(* com.acme..*Service.*(..))` or `@annotation(org.springframework.transaction.annotation.Transactional)`. - **Advice**: the code that runs at a join point — `@Before`, `@After`, `@AfterReturning`, `@AfterThrowing`, `@Around` (the most powerful; it wraps the call via a `ProceedingJoinPoint` you must `proceed()`). - **Aspect**: a class holding pointcuts + advice, marked `@Aspect`. - **Weaving**: connecting aspects to target code. Spring AOP weaves at **runtime via proxies**. ## How Spring AOP weaves (the mechanism) Spring AOP uses **runtime proxying**. When the container creates a bean that matches an aspect's pointcut, a `BeanPostProcessor` (`AnnotationAwareAspectJAutoProxyCreator`, enabled by `@EnableAspectJAutoProxy` — Spring Boot turns it on automatically) replaces the bean in the context with a **proxy** that has the same type: - **JDK dynamic proxy** — used when the target implements at least one interface. The proxy implements those interfaces and forwards to the target. Callers must reference the interface type. - **CGLIB proxy** — a runtime-generated **subclass** of the target class. Used when there is no interface, or when `proxyTargetClass=true`. **Spring Boot sets `proxyTargetClass=true` by default**, so CGLIB is the common case. Every *external* call goes: `caller -> proxy -> advice chain -> target method`. Because the proxy is created by composition at runtime, **no build step, no javaagent, no special compiler** is needed — it is ordinary Java bytecode generation at startup. ## Note on annotation style vs framework Spring AOP borrows AspectJ's **annotation syntax** (`@Aspect`, `@Pointcut`, `execution(...)`) and the AspectJ pointcut *parser*. This confuses people: using `@Aspect` does **not** mean you are using the AspectJ *weaver*. Spring AOP only understands a **subset** of AspectJ pointcut designators (no `call`, `get`, `set`, `withincode`, etc.) and still weaves with proxies. ## Key limitations (direct consequences of proxying) - Only **public method executions** on **Spring beans** are advisable (CGLIB can technically touch protected, but the model targets public). Private, static, and `final` methods, and `final` classes, cannot be proxied. - **Self-invocation** (`this.other()` inside the same class) skips the proxy — the advice does not run. - Plain objects you `new` yourself are never advised. ## When it is enough For 95% of apps — transactions, security, method logging on service beans — Spring AOP's proxy model is the right, zero-friction choice. You reach for full AspectJ only when you need richer join points or must advise non-Spring objects.

  • Which proxy type does Spring Boot use by default and why does it matter?
    CGLIB, because Boot sets proxyTargetClass=true. It means the target does not need an interface, but the class/method cannot be final, and callers can inject the concrete type.
  • Name two things Spring AOP cannot advise.
    Field access and constructors (no such join points); also private/static/final methods, self-invoked calls, and any object not managed by Spring.

saying these in an interview costs you the question

  • Thinking @Aspect / @EnableAspectJAutoProxy means you are running the AspectJ weaver
  • Believing Spring AOP can advise fields or constructors
  • Claiming it works on any Java object, not just Spring beans
  • Saying it needs a special compiler or javaagent

context