If the order attribute is not configured for @Transactional annotation, then the Advisor which is responsible for transaction attribute - AbstractPointcutAdvisor
(in fact, one of the subclasses of it) will return Ordered.LOWEST_PRECEDENCE, which is defined as Integer.MAX_VALUE.
The Advisor which is responsible for custom AOP advice, a subclass of the same AbstractPointcutAdvisor, will look whether the actual Advice implements Ordered interface, and if it does, the provided value will be used during the sorting.
If custom AOP advice does not implement Ordered interface, the Advisor returns the same default Ordered.LOWEST_PRECEDENCE and the result of the sorting becomes slightly unpredictable.
So, configuring the order attribute for @Transactional annotation e.g. like this
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd>
.......
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" order="[Order for @Transactional]">
<beans/>
and your custom AOP advice implementation looks like this
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.Ordered;
@Aspect
public class CustomAspect implements Ordered {
@Around(value = "@annotation(CustomAnnotation)")
public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
...
}
....
@Override
public int getOrder() {
return [Order for @CustomAnnotation];
}
....
}
then you probably have all the freedom (yet, statically) with the ordering throughout your application.
Under the hood, it's AspectJAwareAdvisorAutoProxyCreator who upon a Proxy initialization sorts the Advisors using the comparator org.springframework.aop.aspectj.autoproxy.AspectJPrecedenceComparator which delegates the sorting to OrderComparator.
Later on, upon the actual execution, a concrete implementation of AopProxy holds for a specific method an array of the advices, whom it calls interceptors, and this might be used for dynamic reordering, I guess, but none of these things seems to me easily accessible and/or configurable.
My environment is Spring Beans, TX, AOP - all version 4.0.3. I also have two custom Transaction Managers, one is Hibernate-bound and one is JDBC DataSource-bound, but I don't think it matters here
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…