skip to content

@EnableAspectJAutoProxy & Auto-Proxy Creator

@EnableAspectJAutoProxy registers the BeanPostProcessor that wraps matched beans in proxies, and Spring Boot switches it on for you. Knowing which component does the wrapping is what lets you debug advice that never fires.

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

questions

5

What does @EnableAspectJAutoProxy do in a Spring application?

level: juniorimportance: must knowfreq 70%

answer

  1. Enables @AspectJ support
  2. Registers AnnotationAwareAspectJAutoProxyCreator
  3. BeanPostProcessor wraps matched beans
  4. Boot enables it by default
  5. attrs: proxyTargetClass, exposeProxy

basics

~10 s

It turns on Spring's support for @AspectJ-style aspects. Spring then scans for @Aspect beans and automatically wraps matching beans in proxies so the aspect's advice runs around their methods.

solid answer

~40 s

@EnableAspectJAutoProxy is a configuration annotation you put on a @Configuration class to enable @AspectJ-style aspect support. It registers an infrastructure bean called AnnotationAwareAspectJAutoProxyCreator, which is a BeanPostProcessor. At startup Spring finds all @Aspect-annotated beans, and the auto-proxy creator inspects every other bean: if a bean has a method matched by an aspect's pointcut, Spring wraps that bean in an AOP proxy (JDK dynamic proxy or CGLIB). Callers get the proxy from the container, and when they invoke a matched method the aspect's advice (e.g. @Before, @Around) runs. Without this annotation (or Boot's auto-config), @Aspect classes are ignored and no proxying happens. Its attributes are proxyTargetClass and exposeProxy.

code

java · 19 lines
java
@Configuration
@EnableAspectJAutoProxy
public class AopConfig {
}

@Aspect
@Component
public class TimingAspect {
    @Around("execution(* com.example.service..*(..))")
    public Object timed(ProceedingJoinPoint pjp) throws Throwable {
        long start = System.nanoTime();
        try {
            return pjp.proceed(); // call the real bean method
        } finally {
            long ms = (System.nanoTime() - start) / 1_000_000;
            System.out.println(pjp.getSignature() + " took " + ms + "ms");
        }
    }
}

go deeper

for a junior

Know it enables @Aspect support and that proxies are what make advice run.

for a middle

Name the registered bean (AnnotationAwareAspectJAutoProxyCreator) and that it's a BeanPostProcessor.

for a senior

Explain the registrar import, advisor building, and the two attributes; contrast with Boot auto-config.

for a principal

Discuss why it's a BeanPostProcessor, ordering, and the trade-offs vs compile/load-time weaving.

## What it is `@EnableAspectJAutoProxy` is a Spring annotation placed on a `@Configuration` class. Its job is to switch on **AOP (Aspect-Oriented Programming)** using `@AspectJ` annotations. ### Key terms defined - **AOP / aspect**: a way to add cross-cutting behavior (logging, transactions, security, caching, timing) to many methods without editing each one. The reusable behavior is an *aspect*. - **@Aspect**: a class-level annotation (from AspectJ) marking a class as an aspect. Inside it you declare **advice** methods like `@Before`, `@After`, `@Around` tied to a **pointcut** (an expression selecting which methods to intercept). - **Proxy**: Spring does not modify your bean's bytecode. Instead it creates a wrapper object (the proxy) that implements the same interface or subclasses your class. The proxy intercepts calls, runs the advice, then delegates to the real bean. - **BeanPostProcessor**: a container extension point that can inspect/replace each bean after it is created. Spring's proxying is implemented as one. ### How @EnableAspectJAutoProxy works, step by step 1. The annotation imports `AspectJAutoProxyRegistrar`, which registers an infrastructure bean named `org.springframework.aop.config.internalAutoProxyCreator` — concretely an **`AnnotationAwareAspectJAutoProxyCreator`**. 2. That creator is a `BeanPostProcessor`. During context startup it collects all beans annotated `@Aspect` and turns their advice into Spring **Advisors** (pointcut + advice pairs). 3. As each ordinary bean finishes initialization, the creator's `postProcessAfterInitialization` checks whether any advisor's pointcut matches a method on that bean. If yes, it returns an **AOP proxy** instead of the raw bean. 4. Other beans (and the container) receive the proxy. Invoking a matched method flows through the advice. ### Without it If you neither add `@EnableAspectJAutoProxy` nor rely on Spring Boot's auto-configuration, your `@Aspect` classes are just ordinary beans — their advice never runs because nothing creates the proxies. ### Spring Boot note In Spring Boot you usually do **not** write `@EnableAspectJAutoProxy` yourself: `AopAutoConfiguration` enables it automatically when `aspectjweaver` is on the classpath. ### Attributes - `proxyTargetClass` (default `false`): `false` = use a JDK dynamic proxy when the bean implements an interface, else CGLIB; `true` = always CGLIB class-based proxy. - `exposeProxy` (default `false`): when `true`, the current proxy is available via `AopContext.currentProxy()` — used to work around the self-invocation limitation. ### When to use Write it explicitly in a plain Spring (non-Boot) app, or when you want to force CGLIB (`proxyTargetClass = true`) or `exposeProxy = true`.

  • If you forget @EnableAspectJAutoProxy in a non-Boot app, what happens to your @Aspect class?
    It becomes an ordinary bean and its advice is never applied — no proxies are created, so pointcuts never fire. Nothing errors; the aspect is simply silent.
  • Do you need @EnableAspectJAutoProxy in Spring Boot?
    Usually no. Boot's AopAutoConfiguration enables aspect auto-proxying by default when aspectjweaver is on the classpath (controlled by spring.aop.auto).

saying these in an interview costs you the question

  • Thinking it modifies your class bytecode instead of creating a proxy wrapper
  • Believing advice runs even without proxy creation
  • Confusing it with @EnableTransactionManagement or @EnableCaching (those register their own advisors)
  • Assuming you must always add it in Spring Boot

context

open as a page

How does AnnotationAwareAspectJAutoProxyCreator actually create proxies, and why is it a BeanPostProcessor?

level: middleimportance: must knowfreq 55%

basics

~20 s

It's a BeanPostProcessor, so Spring runs it after each bean is created. In postProcessAfterInitialization it checks if any aspect's pointcut matches the bean; if so it returns an AOP proxy that wraps the bean instead of the raw object.

open as a page

In Spring Boot, how is aspect auto-proxying enabled, and how does it differ from a plain Spring app?

level: middleimportance: should knowfreq 45%

basics

~10 s

Spring Boot enables it automatically via AopAutoConfiguration when aspectjweaver is on the classpath, so you normally don't add @EnableAspectJAutoProxy. In a plain Spring app you must add the annotation yourself.

open as a page

Explain the proxyTargetClass and exposeProxy attributes of @EnableAspectJAutoProxy and when you'd set each.

level: seniorimportance: should knowfreq 40%

basics

~10 s

proxyTargetClass=true forces CGLIB class proxies instead of JDK interface proxies. exposeProxy=true publishes the current proxy via AopContext.currentProxy() so a bean can call its own advised methods through the proxy instead of bypassing it.

open as a page

As a BeanPostProcessor, what ordering and eligibility hazards does the auto-proxy creator introduce, and how do you reason about which beans actually get advised?

level: principalimportance: nice to knowfreq 22%

basics

~20 s

Because proxying happens in a BeanPostProcessor after init, any bean created before that processor is active — like other BeanPostProcessors and their dependencies — won't be proxied. Aspects and AOP infrastructure beans are also skipped by design.

open as a page