Spring AOP XML配置和注解配置 总结学习
2018-02-17 本文已影响37人
jwfy
在前面的三篇中分别介绍了AOP的两种使用方法和具体的源码学习,现在来总结一下这两种方法的同异以及一些之前未注意的细节。
对象实例化差异
XML配置扫描到<aop:config>
就会创建生成AspectJAwareAdvisorAutoProxyCreator对象,而注解配置在扫描到<aop:aspectj-autoproxy />
则创建生成AnnotationAwareAspectJAutoProxyCreator对象,如下图两个类的UML图,注解的类是又扩展了一些属性以及功能。
public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator {
private List<Pattern> includePatterns;
// 正则匹配的类名称,放在aop:include元素中,扩展实现对合适名称的判断
// 关注isEligibleBean方法(从函数名称也可以看出判断是否是合适的bean)
private AspectJAdvisorFactory aspectJAdvisorFactory;
// advisor的工厂
private BeanFactoryAspectJAdvisorsBuilder aspectJAdvisorsBuilder;
protected List<Advisor> findCandidateAdvisors() {
List<Advisor> advisors = super.findCandidateAdvisors();
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
// 拓展了找出所有合适的advisor的方法,也恰好体现了两种注解方式的真正差异的地方
return advisors;
}
...
获取PointCut、advisor信息差异
这点差异在XML配置的源码学习和注解配置的源码学习中都已经介绍清楚了,现在总结下
- XML配置中详细解析XML的各个节点数据,不管是pointCut还是advisor,都会生产一个beandefinition,会以
#+序号
为beanName的结尾名称。 - 注解配置会先扫描beandefinition集合中所有类型为Object的beandefinition集合,通过includePatterns参数进行正则的匹配,过滤出合适的beandefinition的bean,过滤出注解为
@Aspect
的bean,扫描bean的所有方法存储到cache中
扫描beandefinition集合过滤操作只会执行一次!
执行的结果会存储到cache中,便于后面每次执行
两种的差异在于注解配置只会产生一个beandefinition,然后所有的AOP信息都会存储在该beandefinition实例化的对象中,而XML则会每个AOP配置都会映射到一个beandefinition,后续每个beandefinition绑定和自己关联的AOP信息
排序规则
两种方法的排序规则调用位置是一致的,而且排序规则也是完全一样的(公用同一套代码逻辑)
AbstractAdvisorAutoProxyCreator 文件
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
List<Advisor> candidateAdvisors = findCandidateAdvisors();
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
// 这个sort就是决定了advisor的排序
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
protected List<Advisor> sortAdvisors(List<Advisor> advisors) {
AnnotationAwareOrderComparator.sort(advisors);
// 该类是继承Comparator,实现自定义的排序
// 就AOP排序来说,是根据各个类的declarationOrder进行排序的
// PS:该bean排序在spring中被广泛使用
return advisors;
}
AOP中几种advisor的默认declarationOrder值情况如下表,需要注意到这个规则和严格的执行顺序不一样,真正执行的时候ProxyFactory还需要进行wrap处理。
类名称 | declarationOrder值 | 说明 |
---|---|---|
AspectJAfterThrowingAdvice | 9 | afterThrow |
AspectJAfterReturningAdvice | 7 | afterReturn |
AspectJMethodBeforeAdvice | 5 | methodBefore |
AspectJAroundAdvice | 3 | around |
AspectJAfterAdvice | 1 | after |