Description
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}
<bean class="com.kendelong.util.circuitbreaker.CircuitBreakerAspect" scope="prototype">
<property name="graphiteClient" ref="graphiteClient"/>
<property name="order" value="100" />
</bean>
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:
- ScheduledAnnotationBeanPostProcessor should reliably apply after AnnotationAwareAspectJAutoProxyCreator [SPR-14692] #19256 ScheduledAnnotationBeanPostProcessor should reliably apply after AnnotationAwareAspectJAutoProxyCreator