Ken DeLong opened SPR-14959 and commented
I am using Java 8, Boot 1.4.1, and Spring 4.3.3 (from Boot).
I have a set of aspects that I instantiate as prototype scope, because they maintain state (like a CircuitBreaker) and they are individually exported to JMX for monitoring purposes. https://github.com/kenwdelong/stability-utils
The interceptors under consideration are: https://github.com/kenwdelong/stability-utils/blob/stability-utils-1.3.10/src/main/java/com/kendelong/util/circuitbreaker/CircuitBreakerAspect.javahttps://github.com/kenwdelong/stability-utils/blob/stability-utils-1.3.10/src/main/java/com/kendelong/util/concurrency/ConcurrencyLimitingAspect.java https://github.com/kenwdelong/stability-utils/blob/stability-utils-1.3.10/src/main/java/com/kendelong/util/performance/PerformanceMonitoringAspect.java https://github.com/kenwdelong/stability-utils/blob/stability-utils-1.3.10/src/main/java/com/kendelong/util/retry/RetryInterceptor.java
The ordering of these interceptors is critical (and also the ordering relative to TransactionInterceptor and MethodSecurityInterceptor). However, the Ordered interface is not being respected here. My configuration (XML here, but JavaConfig behaves the same) is
{code:html/xml}
\
However, the aspects are ordered randomly.
I tried to trace this through the code, to the AnnotationAwareOrderComparator.findOrder() method. It returns after the first check for the Ordered interface (line 65), which is good, but the value it returns is Integer.MAX_VALUE, which is bad. OrderComparator.findOrder() returns the Integer. From there it asks the LazySingletonAspectInstanceFactoryDecorator for the order, which delegates to BeanFactoryAspectInstanceFactory.getOrder(). Finally, that method calls OrderUtils.getOrder() (line 68) but this method ONLY looks for the annotation then gives up and assigns the default value. I think perhaps this method should also check for the Ordered interface and call that getOrder() method.
If I use the @Order annotation on my aspects, it works fine. But as this is a reusable library, hard-coding the order values may be incompatible with the project using the library.
Affects: 4.3.3
Reference URL: http://stackoverflow.com/questions/40768177/spring-aop-prototype-scoped-aspects-are-firing-out-of-order
Issue Links: - #19256 ScheduledAnnotationBeanPostProcessor should reliably apply after AnnotationAwareAspectJAutoProxyCreator
Comment From: spring-projects-issues
Juergen Hoeller commented
This is currently explicitly limited to singleton beans: See BeanFactoryAspectInstanceFactory
's getOrder
implementation and documentation. For non-singleton beans, we'd have to create a temporary instance just to retrieve the order value, since the Ordered
interface implies instance-specific order state.
We can certainly revisit this but might only be able to do so for 5.0.