总结摘要
Spring AOP Aspect 执行顺序
源码分析
Advisor 排序规则
- Aspect Bean 顺序,根据 Bean 的 Order 注解或其它 Order 标识排序。
- Aspect 注解顺序 Around.class,Before.class,After.class,AfterReturning.class,AfterThrowing.class。
- 方法名称。
注意事项
After、AfterReturning和AfterThrowing类型较为特殊,优先级越高,生效时机越晚。
以After为例说明。
当声明2个After类型切面,aspect_after1的优先级高于aspect_after2,则两个切面的逻辑等价于如下
1
2
3
4
5
6
7
8
9
10
11
12
13
| public void aspect_after1 {
actual_method_maybe_with_other_aspcet();
after1_feature();
}
public void aspect_after2 {
actual_method_maybe_with_other_aspcet();
after2_feature();
}
public void main_aop {
aspect_after1();
}
|
最终执行流程为
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| aspect_after1()
|
|
\/
aspect_after2()
|
|
\/
actual_method()
|
|
\/
after2_feature()
|
|
\/
after1_feature()
|
实现
- org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory#adviceMethodComparator 对 Aspect Bean 中的 Aspect 方法排序,首先根据注解,其次根据方法名称。
- org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator#sortAdvisors 对 Aspect Bean 排序,使用稳定的拓扑排序算法,基于规则 org.springframework.core.annotation.AnnotationAwareOrderComparator#INSTANCE。
验证
1
2
3
4
5
6
7
8
9
10
11
| @Order(1)
@Aspect
@Component
// [SpringAOP][LoggingA]
public class LoggingAAspectSpringBean {}
@Order(10)
@Aspect
@Component
// [SpringAOP][LoggingB]
public class LoggingBAspectSpringBean {}
|
执行日志
1
2
3
4
5
6
7
8
9
10
11
| [SpringAOP][LoggingA] Around begin action: testPublic
[SpringAOP][LoggingA] Before action: testPublic
[SpringAOP][LoggingB] Around begin action: testPublic
[SpringAOP][LoggingB] Before action: testPublic
testPublic
[SpringAOP][LoggingB] AfterReturning action: testPublic
[SpringAOP][LoggingB] After action: testPublic
[SpringAOP][LoggingB] Around end action: testPublic
[SpringAOP][LoggingA] AfterReturning action: testPublic
[SpringAOP][LoggingA] After action: testPublic
[SpringAOP][LoggingA] Around end action: testPublic
|

LoggingAAspectSpringBean


LoggingBAspectSpringBean


org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator#sortAdvisors
(org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findEligibleAdvisors)
(org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#getAdvicesAndAdvisorsForBean)

END