Open aviv-amdocs opened 6 days ago
The ajc-compiled check is only reliable for aspect classes, not for target classes being weaved. We'll try to revisit this but I'm not sure this will ever be 100% reliable since we are checking for internal ajc markers there. Recent AspectJ recommendations for reusable aspects do not differentiate between the usage model anymore, suggesting ajc-pre-compiled aspects to be usable everywhere, which triggered our change where Spring AOP does not exclude ajc-compiled aspects for proxying anymore.
Conceptually, the root of this problem is the exposure of the aspect class as a Spring bean. With Spring auto-proxying being active (which it is by default in Boot), Spring AOP will by design consider any such aspect bean for regular AOP proxying. If an aspect is exclusively meant to be used with ajc compilation (as performed by the AspectJ Maven plugin), you either need to turn off Boot's auto-proxying auto-configuration - or not expose the AspectJ-managed aspect as a Spring bean to begin with.
With ajc, an aspect is an ajc-managed singleton instance anyway, not a real Spring bean with a Spring-managed lifecycle. So I assume that the only reason for bean exposure is autowiring your interceptor. Consider revising your interceptor setup along the following lines, with the interceptor setting itself into the ajc-managed aspect instance, and no @Bean AspectInjector
method at all anymore. This avoids the mixture of models and lifecycles and will work reliably with any Spring version:
@Bean
public Interceptor interceptor() {
Interceptor interceptor = new Interceptor();
Aspects.aspectOf(AspectInjector.class).interceptor = interceptor;
return interceptor;
}
Affects: 6.1.7-6.1.13
This might be a special case of #32970, except it's not fixed yet. We have both
aspectj-maven-plugin
and@Aspect
.Demo code (short):
mvn test
will run a failing test.mvn test -Dspring-framework.version=6.1.6
will pass the test.We have this pattern where we use an Aspect interceptor to replace exceptions thrown by some library with application-specific exceptions. This worked fine until Spring Framework 6.1.7, and since then, the interceptor is triggered (weaved?) twice. The interceptor doesn't expect the exception it's provided, so it throws an exception nobody expects (In the demo, it just wraps the exception with a new one, and the test checks for
getCause().getMessage()
).