情景

自己定义了一个 AOP,发现 spring 的 @Transactional 变得无效了。

如何指定优先级

注解

public @interface Order {

	/**
	 * The order value.
	 * <p>Default is {@link Ordered#LOWEST_PRECEDENCE}.
	 * @see Ordered#getOrder()
	 */
	int value() default Ordered.LOWEST_PRECEDENCE;

}

接口

public interface Ordered {

	/**
	 * Get the order value of this object.
	 * <p>Higher values are interpreted as lower priority. As a consequence,
	 * the object with the lowest value has the highest priority (somewhat
	 * analogous to Servlet {@code load-on-startup} values).
	 * <p>Same order values will result in arbitrary sort positions for the
	 * affected objects.
	 * @return the order value
	 * @see #HIGHEST_PRECEDENCE
	 * @see #LOWEST_PRECEDENCE
	 */
	int getOrder();

}

到底优先级是怎么执行的?

springBoot 的注解相关配置

直接根据注解 @EnableTransactionManagement 查看类ProxyTransactionManagementConfiguration

@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
	BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
	advisor.setTransactionAttributeSource(transactionAttributeSource());
	advisor.setAdvice(transactionInterceptor());
	advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
	return advisor;
}

这里的默认值 this.enableTx.<Integer>getNumber("order") 是一个很大的值。

执行拦截的核心代码

执行拦截的类 TransactionInterceptor

@Override
public Object invoke(final MethodInvocation invocation) throws Throwable {
	// Work out the target class: may be {@code null}.
	// The TransactionAttributeSource should be passed the target class
	// as well as the method, which may be from an interface.
	Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
	// Adapt to TransactionAspectSupport's invokeWithinTransaction...
	return invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() {
		@Override
		public Object proceedWithInvocation() throws Throwable {
			return invocation.proceed();
		}
	});
}

到底是怎么执行的?

根据测试,发现 spring 的 aop 应该不是线性执行的。

spring 的 aop 应该嵌套执行的。

比如自定义 MyAspect,指定一个较小的 order(执行优先级较高)。

会先进入 MyAspect 的入口,然后进入 @Trasactional 的方法。然后执行 MyAspect 的方法结束。