AspectJ 下 Advisor 的排序过程
在 AbstractAdvisorAutoProxyCreator#findEligibleAdvisors 方法中,找到 BeanFactory 中所有的 Advisor 后,针对当前 beanClass 进行过滤,筛选出符合当前 beanClass 的 Advisor,称之为 eligibleAdvisors。接着对 eligibleAdvisors 进行扩展,AspectJ 下会在集合首位添加一个 ExposeInvocationInterceptor.ADVISOR,这是一个 DefaultPointcutAdvisor,持有的 Advice 为一个 ExposeInvocationInterceptor 对象。接着对这个 eligibleAdvisors 进行排序。
// 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()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
// AspectJAwareAdvisorAutoProxyCreator
@Override
protected List<Advisor> sortAdvisors(List<Advisor> advisors) {
List<PartiallyComparableAdvisorHolder> partiallyComparableAdvisors = new ArrayList<>(advisors.size());
// 封装 PartiallyComparableAdvisorHolder 集合
for (Advisor advisor : advisors) {
// 默认的优先级比较器 AspectJPrecedenceComparator
partiallyComparableAdvisors.add(
new PartiallyComparableAdvisorHolder(advisor, DEFAULT_PRECEDENCE_COMPARATOR));
}
// 排序
List<PartiallyComparableAdvisorHolder> sorted = PartialOrder.sort(partiallyComparableAdvisors);
if (sorted != null) {
List<Advisor> result = new ArrayList<>(advisors.size());
for (PartiallyComparableAdvisorHolder pcAdvisor : sorted) {
result.add(pcAdvisor.getAdvisor());
}
return result;
}
else {
return super.sortAdvisors(advisors);
}
}
针对每一个 advisor,封装一个 PartiallyComparableAdvisorHolder,这是一个 AspectJAwareAdvisorAutoProxyCreator 中的内部类,持有 Advisor 和 Comparator 两个字段,实现了 org.aspectj.util.PartialOrder$PartialComparable 接口,PartialOrder 是一个排序的工具类。
定义的 Comparator 为 AspectJPrecedenceComparator。
public AspectJPrecedenceComparator() {
this.advisorComparator = AnnotationAwareOrderComparator.INSTANCE;
}
定义完 partiallyComparableAdvisors 集合之后,开始对其进行排序。
// PartialOrder
public static <T extends PartialComparable> List<T> sort(List<T> objects) {
// lists of size 0 or 1 don't need any sorting
if (objects.size() < 2) {
return objects;
}
// ??? we might want to optimize a few other cases of small size
// ??? I don't like creating this data structure, but it does give good
// ??? separation of concerns.
// 我不喜欢创建这样的数据结构,但是它确实很好的将关注点分离了
List<SortObject<T>> sortList = new LinkedList<>();
for (T object : objects) {
addNewPartialComparable(sortList, object);
}
// System.out.println(sortList);
// now we have built our directed graph
// use a simple sort algorithm from here
// can increase efficiency later
// List ret = new ArrayList(objects.size());
final int N = objects.size();
for (int index = 0; index < N; index++) {
// System.out.println(sortList);
// System.out.println("-->" + ret);
SortObject<T> leastWithNoSmallers = null;
// 遍历 sortList,寻找最小的,smallerObjects 数量为0,表明没有比它更小的
for (SortObject<T> so: sortList) {
if (so.hasNoSmallerObjects()) {
if (leastWithNoSmallers == null || so.object.fallbackCompareTo(leastWithNoSmallers.object) < 0) {
leastWithNoSmallers = so;
}
}
}
// 不存在最小的,返回 null
if (leastWithNoSmallers == null) {
return null;
}
removeFromGraph(sortList, leastWithNoSmallers);
// 重新设置 objects 中元素次序
objects.set(index, leastWithNoSmallers.object);
}
return objects;
}
首先创建了一个 SortObject 的集合,命名为 sortList。这里的注释也挺有意思的,作者说他并不喜欢创建这样的数据结构。
遍历 objects,执行 addNewPartialComparable。
private static <T extends PartialComparable> void addNewPartialComparable(List<SortObject<T>> graph, T o) {
// 第一次由于 graph 集合是空的,所以只添加
// 第二次 graph 不为空,遍历 graph,将之前添加的作为 other
SortObject<T> so = new SortObject<>(o);
for (SortObject<T> other : graph) {
so.addDirectedLinks(other);
}
graph.add(so);
}
// SortObject
void addDirectedLinks(SortObject<T> other) {
// 当前 SortObject 中 object 和 other 中的 object 比较
int cmp = object.compareTo(other.object);
if (cmp == 0) {
return;
}
if (cmp > 0) {
this.smallerObjects.add(other);
other.biggerObjects.add(this);
} else {
this.biggerObjects.add(other);
other.smallerObjects.add(this);
}
}
// PartiallyComparableAdvisorHolder
@Override
public int compareTo(Object obj) {
Advisor otherAdvisor = ((PartiallyComparableAdvisorHolder) obj).advisor;
// 利用默认的优先级比较器比较两个 advisor
return this.comparator.compare(this.advisor, otherAdvisor);
}
将 PartiallyComparableAdvisorHolder 传递给 SortObject 中的 object,每个 SortObject 中都存在两个 SortObject 集合,一个命名为 smallerObjects,即存储比当前 object 小的 SortObject 对象,一个命名为 biggerObjects,存储比当前 object 大的 SortObject 对象。
在 PartiallyComparableAdvisorHolder#compareTo 中,利用传入的比较器比较两个 Advisor。
// AspectJPrecedenceComparator
@Override
public int compare(Advisor o1, Advisor o2) {
// advisorComparator 为 AnnotationAwareOrderComparator.INSTANCE
int advisorPrecedence = this.advisorComparator.compare(o1, o2);
// order 相等,且定义在同一个切面类中
if (advisorPrecedence == SAME_PRECEDENCE && declaredInSameAspect(o1, o2)) {
advisorPrecedence = comparePrecedenceWithinAspect(o1, o2);
}
return advisorPrecedence;
}
AspectJPrecedenceComparator 又将比较过程委托给其持有的 advisorComparator 去执行,这是一个 AnnotationAwareOrderComparator。
org.springframework.core.OrderComparator 中定义了 compare 方法。
// OrderComparator
@Override
public int compare(@Nullable Object o1, @Nullable Object o2) {
return doCompare(o1, o2, null);
}
private int doCompare(@Nullable Object o1, @Nullable Object o2, @Nullable OrderSourceProvider sourceProvider) {
boolean p1 = (o1 instanceof PriorityOrdered);
boolean p2 = (o2 instanceof PriorityOrdered);
// o1 PriorityOrdered,o2 非 PriorityOrdered
// 返回 -1,即 o1 < o2
if (p1 && !p2) {
return -1;
}
// o2 PriorityOrdered,o1 非 PriorityOrdered
// 返回 1,即 o1 > o2
else if (p2 && !p1) {
return 1;
}
// sourceProvider null
int i1 = getOrder(o1, sourceProvider);
int i2 = getOrder(o2, sourceProvider);
return Integer.compare(i1, i2);
}
// OrderComparator
protected int getOrder(@Nullable Object obj) {
if (obj != null) {
Integer order = findOrder(obj);
if (order != null) {
return order;
}
}
return Ordered.LOWEST_PRECEDENCE;
}
获取 order,进行比较。子类 AnnotationAwareOrderComparator 重写了 findOrder 方法。
// AnnotationAwareOrderComparator
@Override
@Nullable
protected Integer findOrder(Object obj) {
Integer order = super.findOrder(obj);
if (order != null) {
return order;
}
// 注解中获取 order
return findOrderFromAnnotation(obj);
}
// 父类 OrderedComparator
@Nullable
protected Integer findOrder(Object obj) {
return (obj instanceof Ordered ? ((Ordered) obj).getOrder() : null);
}
先通过 OrderedComparator#findOrder 获取 order,存在就直接返回了,不存在调用 AnnotationAwareOrderComparator#findOrderFromAnnotation 从注解中获取 order。
针对当前情况,传入的两个比较对象都是 Advisor。
配置示例可以参考 AspectJ 对于 AOP 的实现 中 XML 下的配置。
在 AspectJ 基于 XML 的实现下,各标签对应的 Advisor 如下:
标签名称 | Advisor 类型 | 是否实现 Ordered 接口 |
advisor | DefaultBeanFactoryPointcutAdvisor | 是 |
aspect | AspectJPointcutAdvisor | 是 |
除此之外,还有扩展时添加的 ExposeInvocationInterceptor.ADVISOR,Advisor 类型为 DefaultPointcutAdvisor。
DefaultBeanFactoryPointcutAdvisor 和 DefaultPointcutAdvisor 都通过继承AbstractPointcutAdvisor,实现了 Ordered 接口。AspectJPointcutAdvisor 自己实现了 Ordered 接口。
先来看 AbstractPointcutAdvisor 实现的 getOrder 方法。
// AbstractPointcutAdvisor
@Override
public int getOrder() {
// 获取 order
if (this.order != null) {
return this.order;
}
Advice advice = getAdvice();
if (advice instanceof Ordered) {
return ((Ordered) advice).getOrder();
}
return Ordered.LOWEST_PRECEDENCE;
}
XML 中在 advisor 标签中指定的 order 属性,在属性填充时,已经传递给了 AbstractPointcutAdvisor 中 order 属性,此处直接获取,如果 XML 中未指定,取持有的 advice 中的 order,如果都未指定,返回 Ordered.LOWEST_PRECEDENCE,其实是 Integer.MAX_VALUE,即 order 值越大,优先级越低。
先来看 ExposeInvocationInterceptor.ADVISOR,未设置 order,所以从持有的 Advice 获取,其持有的 Advice 为 ExposeInvocationInterceptor。
// ExposeInvocationInterceptor
@Override
public int getOrder() {
// 最高优先级 -2147483648 + 1 = -2147483647,数值越小,优先级越高
return PriorityOrdered.HIGHEST_PRECEDENCE + 1;
}
计算后,返回值为 -2147483647,可以认为优先级最高。
再来看 DefaultBeanFactoryPointcutAdvisor,设置优先级为 2,AbstractPointcutAdvisor#getOrder 时,order 不为 null,直接就返回了。
接着看 AspectJPointcutAdvisor。aspect 标签下的每一个通知对应一个 AspectJPointcutAdvisor,由于 order 定义在 aspect 标签中,所以这两个 AspectJPointcutAdvisor 拥有的 order 一样。此时在 AspectJPrecedenceComparator#compare 方法中,判断切面方法是否在同一个切面类中,在同一个切面类中则调用 AspectJPrecedenceComparator#comparePrecedenceWithinAspect。
// AspectJPrecedenceComparator
private int comparePrecedenceWithinAspect(Advisor advisor1, Advisor advisor2) {
// advisor1 和 advisor2 是否存在后置通知
boolean oneOrOtherIsAfterAdvice =
(AspectJAopUtils.isAfterAdvice(advisor1) || AspectJAopUtils.isAfterAdvice(advisor2));
// declarationOrder 值相减 3-1
int adviceDeclarationOrderDelta = getAspectDeclarationOrder(advisor1) - getAspectDeclarationOrder(advisor2);
// 存在后置通知
if (oneOrOtherIsAfterAdvice) {
// the advice declared last has higher precedence
// 后定义的 advice 拥有更高的优先级
if (adviceDeclarationOrderDelta < 0) {
// advice1 was declared before advice2
// so advice1 has lower precedence
return LOWER_PRECEDENCE; // 1
}
else if (adviceDeclarationOrderDelta == 0) {
return SAME_PRECEDENCE; //0
}
else {
return HIGHER_PRECEDENCE; // -1
}
}
else {
// the advice declared first has higher precedence
// 不存在后置通知,先定义的拥有更高的优先级
if (adviceDeclarationOrderDelta < 0) {
// advice1 was declared before advice2
// so advice1 has higher precedence
return HIGHER_PRECEDENCE; // -1
}
else if (adviceDeclarationOrderDelta == 0) {
return SAME_PRECEDENCE; // 0
}
else {
return LOWER_PRECEDENCE; // 1
}
}
}
// AspectJAopUtils
public static boolean isAfterAdvice(Advisor anAdvisor) {
AspectJPrecedenceInformation precedenceInfo = getAspectJPrecedenceInformationFor(anAdvisor);
// 判断是否是后置通知
if (precedenceInfo != null) {
return precedenceInfo.isAfterAdvice();
}
return (anAdvisor.getAdvice() instanceof AfterAdvice);
}
@Nullable
public static AspectJPrecedenceInformation getAspectJPrecedenceInformationFor(Advisor anAdvisor) {
// AspectJPrecedenceInformation 子类 InstantiationModelAwarePointcutAdvisorImpl 和 AbstractAspectJAdvice
// InstantiationModelAwarePointcutAdvisorImpl 是 AspectJ 注解模式下创建的 Advisor
if (anAdvisor instanceof AspectJPrecedenceInformation) {
return (AspectJPrecedenceInformation) anAdvisor;
}
// AspectJPointcutAdvisor 获取持有 Advice
Advice advice = anAdvisor.getAdvice();
if (advice instanceof AspectJPrecedenceInformation) {
return (AspectJPrecedenceInformation) advice;
}
return null;
}
// AspectJPrecedenceComparator
private int getAspectDeclarationOrder(Advisor advisor) {
AspectJPrecedenceInformation precedenceInfo = AspectJAopUtils.getAspectJPrecedenceInformationFor(advisor);
return (precedenceInfo != null ? precedenceInfo.getDeclarationOrder() : 0);
}
Advisor 位于同一个 aspect 标签下,order 相等,此时通过 AbstractAspectJAdvice 中 declarationOrder 来进行比较。在定义 adviceDefinition 时添加 declarationOrder,其实就是通知子节点顺序。
xml 下节点顺序:
<aop:aspect>
0 [注释]
1 <aop:before>
2 [注释]
3 <aop:after>
4 [注释]
</aop:aspect>
所以 <aop:before> 的 declarationOrder 为 1,<aop:after> 的 declarationOrder 为 3。
接着,判断是否存在后置通知,存在后置通知时,后定义的 Advisor 优先级更高,不存在后置通知时,先定义的 Advisor 优先级更高。
示例中存在后置通知,按照规则,<aop:after> 标签对应的 AspectJPointcutAdvisor 优先级高。可以认为 <aop:after> 对应的 AspectJPointcutAdvisor 小于 <aop:before> 对应的 AspectJPointcutAdvisor。
确定完比较的规则之后,再回到 SortObject#addDirectedLinks 方法中,填充 smallerObjects 和 biggerObjects。
以示例中得到的 eligibleAdvisors 为例,演示下这个过程。
实际 objects 中各元素为 PartiallyComparableAdvisorHolder,此处为方便说明,以持有的 Advisor 指代。
objects[0] 为 ExposeInvocationInterceptor.ADVISOR,order=-2147483647
objects[1] 为 DefaultBeanFactoryPointcutAdvisor,order=2
objects[2] 为 AspectJPointcutAdvisor,order=1,declarationOrder=1
objects[3] 为 AspectJPointcutAdvisor,order=1,declarationOrder=3
第一次,graph 为空的,遇见 objects[0],封装为 SortObject 之后加入 graph。
第二次,graph[0] = objects[0],当前的 o 为 objects[1],封装 SortObject,由于之后会加入 graph,此处提前将其表示为 graph[1] = objects[1]。
so | other | cmp | smallerObjects/biggerObjects |
graph[1] | graph[0] | 1 | graph[1].smallerObjects = graph[0] graph[0].biggerObjects = graph[1] |
第三次,graph 中已经有两个元素了,graph[0] = objects[0],graph[1] = objects[1],待加入的 graph[2] = objects[2]。循环 graph[0] 和 graph[1],用 graph[2] 分别和 graph[0]、graph[1] 作比较。
so | other | cmp | smallerObjects/biggerObjects |
graph[2] | graph[0] | 1 | graph[2].smallerObjects = graph[0] graph[0].biggerObjects = graph[1],graph[2] |
graph[1] | -1 | graph[1].smallerObjects = graph[0],graph[2] graph[2].biggerObjects = graph[1] |
第四次,graph 中已经有三个元素了,graph[0] = objects[0],graph[1] = objects[1],graph[2] = objects[2],待加入的 graph[3] = objects[3]。循环 graph[0] 、graph[1] 和 graph[2],用 graph[3] 分别和 graph[0]、graph[1]、graph[2] 作比较。
so | other | cmp | smallerObjects/biggerObjects |
graph[3] | graph[0] | 1 | graph[3].smallerObjects = graph[0] graph[0].biggerObjects = graph[1],graph[2],graph[3] |
graph[1] | -1 | graph[1].smallerObjects = graph[0],graph[2],graph[3] graph[3].biggerObjects = graph[1] | |
graph[2] | -1 | graph[2].smallerObjects = graph[0],graph[3] graph[3].biggerObjects = graph[1],graph[2] |
填充完 smallerObjects/biggerObjects 之后,又回到 PartialOrder#sort 方法中,执行 for 循环,在 for 循环中,再遍历 sortList,寻找最小的,smallerObjects 数量为0,表明没有比它更小的。
第一次找到 graph[0],它的 smallerObjects 数量为 0,继而执行 removeFromGraph 方法。
// PartialOrder
private static <T extends PartialComparable> void removeFromGraph(List<SortObject<T>> graph, SortObject<T> o) {
for (Iterator<SortObject<T>> i = graph.iterator(); i.hasNext();) {
SortObject<T> other = i.next();
// 移除
if (o == other) {
i.remove();
}
// ??? could use this to build up a new queue of objects with no
// ??? smaller ones
// 从每一个 other.smallerObjects 里面移除 o
other.removeSmallerObject(o);
}
}
boolean removeSmallerObject(SortObject<T> o) {
smallerObjects.remove(o);
return hasNoSmallerObjects();
}
确定最小的 o 之后,迭代 graph,从 graph 中移除 o,之后从其余的 other 的 smallerObjects 中移除这个最小的。
完成之后在 PartialOrder#sort 进行下一轮循环。
示例如下:
index | leastWithNoSmallers | 移除后 graph | smallerObjects |
0 | graph[0] | graph[1],graph[2],graph[3] | graph[1].smallerObjects = graph[2],graph[3] graph[2].smallerObjects = graph[3] graph[3].smallerObjects 移除后空了 |
1 | graph[3] | graph[1],graph[2] | graph[1].smallerObjects = graph[2] graph[2].smallerObjects 移除后空了 |
2 | graph[2] | graph[1] | graph[1].smallerObjects 移除后空了 |
3 | graph[1] | 空了 | 空了 |
这样,就按优先级顺序,重置了 objects 中各元素的顺序。
再回到 AspectJAwareAdvisorAutoProxyCreator#sortAdvisors 方法中,排序之前将每一个 Advisor 封装成 PartiallyComparableAdvisorHolder,此时需要提取出 Advisor,加入 result 后作为结果返回。
实际上,这是拓扑排序的一种应用,存在的 smallerObjects 表示依赖的活动(activity),smallerObjects 数量为 0,表明不依赖任何活动。绘制出的 AOV 网如下: