Backend Development 8 min read

Why Spring AOP Sometimes Fails to Create Proxies and How to Fix It

This article explains Spring AOP’s core concepts, shows how proxies are normally created with @EnableAspectJAutoProxy, and details several edge cases—such as implementing Advice, Pointcut, Advisor, or using special bean names—where Spring will not generate a proxy, providing code examples and the resulting output for each scenario.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Why Spring AOP Sometimes Fails to Create Proxies and How to Fix It

1. Introduction

Spring AOP (Aspect‑Oriented Programming) is a core feature of the Spring framework that modularizes cross‑cutting concerns such as logging, transaction management, and security by weaving aspects into target objects at runtime using proxies, without modifying the original code.

Core Elements for Proxy Creation

Pointcut : defines which methods are enhanced, usually via expressions based on method name, parameters, annotations, etc.

Advice : the logic to be applied (e.g., Before , After , Around , Throws , Introduction ).

Processor : BeanPostProcessor determines whether a bean matches a pointcut and creates the proxy, returning it to the Spring container.

Typical annotations to enable these features are:

<code>@Configuration
@EnableTransactionManagement // enable @Transactional
@EnableAspectJAutoProxy      // enable AOP proxy creation
@EnableAsync                 // enable @Async support
public class AppConfig {}
</code>

2. Situations Where a Proxy Is Not Created

2.1 Environment Preparation

Define a simple service:

<code>@Service
public class Service {
  public void save() {
    System.out.println("Service save...");
  }
}
</code>

Define an aspect:

<code>@Component
@Aspect
public class LogAspect {
  @Pointcut("execution(* com.pack..*.*(..))")
  private void log() {}

  @Before("log()")
  public void recordLog() {
    System.out.println("before log...");
  }
}
</code>

Running the application normally creates a CGLIB proxy:

<code>ConfigurableApplicationContext context = SpringApplication.run(App.class, args);
Service service = context.getBean(Service.class);
System.out.println(service.getClass());
service.save();
</code>

Output:

<code>class com.pack.Service$$SpringCGLIB$$0
before log...
Service save ...
</code>

2.2 Cases That Prevent Proxy Creation

Service implements Advice <code>public class Service implements Advice {} </code> Output shows no proxy: <code>class com.pack.Service Service save... </code>

Service implements Pointcut <code>public class Service implements Pointcut { // dummy implementations public ClassFilter getClassFilter() { return null; } public MethodMatcher getMethodMatcher() { return null; } } </code> Output: <code>class com.pack.Service Service save... </code>

Service implements AopInfrastructureBean <code>public class Service implements AopInfrastructureBean {} </code> Output: <code>class com.pack.Service Service save... </code>

Service implements Advisor <code>public class Service implements Advisor { // empty implementation public Advice getAdvice() { return null; } } </code> Output is the same—no proxy is created.

Special bean name Using the full package name plus .ORIGINAL prevents proxy creation: <code>@Component("com.pack.Service.ORIGINAL") public class Service {} </code> Output: <code>class com.pack.Service Service save... </code> Changing the bean name to something else restores proxy creation: <code>@Component("xxxooo.ORIGINAL") </code> Resulting output: <code>class com.pack.Service$$SpringCGLIB$$0 before log... Service save ... </code>

Special Advisor A custom AspectJPointcutAdvisor that returns an aspect name matching the bean name also blocks proxy creation: <code>@Component public class LogAdvisor extends AspectJPointcutAdvisor { public LogAdvisor(AbstractAspectJAdvice advice) { super(advice); } @Override public String getAspectName() { return "service"; } } </code> If getAspectName() returns the same name as the service bean, the proxy is not created.

Understanding these edge cases helps developers diagnose why a Spring AOP proxy may not be generated and apply the appropriate fix.

JavaProxySpringBootSpring AOPAspectJ
Spring Full-Stack Practical Cases
Written by

Spring Full-Stack Practical Cases

Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.