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).