Skip to main content
AOP and proxies · Topic 5 of 5

Self-invocation pitfall

Definition​

Advice only runs for calls that go through the proxy. If a method calls another method of the same object with this, the call skips the proxy and the advice (for example @Transactional) does not run. Move the method to another bean to fix it.

Example code​

The advice runs for the outside call only

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

@Service
class ReportService {
void publish() {
System.out.println("publish() calls generate() through this");
generate(); // a plain call on this: the proxy is bypassed
}

void generate() { System.out.println("generate() body"); }
}

@Aspect
@Component
class TraceAspect {
@Before("execution(* ReportService.generate(..))")
void trace() { System.out.println(" >> advice on generate()"); }
}

@ComponentScan
@EnableAspectJAutoProxy
class Demo {
public static void main(String[] args) {
try (var context = new AnnotationConfigApplicationContext(Demo.class)) {
ReportService service = context.getBean(ReportService.class);
service.generate(); // from outside: advice runs
service.publish(); // from inside: advice does NOT run
}
}
}

// Output:
// >> advice on generate()
// generate() body
// publish() calls generate() through this
// generate() body

Finished this page? Track your progress (saved only in your browser).