当前位置: 首页 > article >正文

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 接口
advisorDefaultBeanFactoryPointcutAdvisor
aspectAspectJPointcutAdvisor

除此之外,还有扩展时添加的 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]。

soothercmpsmallerObjects/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] 作比较。

soothercmpsmallerObjects/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] 作比较。

soothercmpsmallerObjects/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 进行下一轮循环。

示例如下:

indexleastWithNoSmallers移除后 graphsmallerObjects
0graph[0]graph[1],graph[2],graph[3]

graph[1].smallerObjects = graph[2],graph[3]

graph[2].smallerObjects = graph[3]

graph[3].smallerObjects 移除后空了

1graph[3]graph[1],graph[2]

graph[1].smallerObjects = graph[2]

graph[2].smallerObjects 移除后空了

2graph[2]graph[1]graph[1].smallerObjects 移除后空了
3graph[1]空了空了

这样,就按优先级顺序,重置了 objects 中各元素的顺序。

再回到 AspectJAwareAdvisorAutoProxyCreator#sortAdvisors 方法中,排序之前将每一个 Advisor 封装成 PartiallyComparableAdvisorHolder,此时需要提取出 Advisor,加入 result 后作为结果返回。

实际上,这是拓扑排序的一种应用,存在的 smallerObjects 表示依赖的活动(activity),smallerObjects 数量为 0,表明不依赖任何活动。绘制出的 AOV 网如下:


http://www.kler.cn/a/542868.html

相关文章:

  • 单张照片可生成写实3D头部模型!Adobe提出FaceLift,从单一的人脸图像中重建出360度的头部模型。
  • 【DeepSeek】在本地计算机上部署DeepSeek-R1大模型实战(完整版)
  • 为什么我用Python控制仪器比C#慢很多?如何优化性能?
  • SQL Server 逻辑查询处理阶段及其处理顺序
  • MYSQL利用PXC实现高可用
  • PHP 完整表单实例
  • untiy3d 触发和碰撞区别
  • innovus如何分步长func和dft时钟
  • MacBook Pro M2安装deepseek
  • C++20 新特性解析
  • 科技查新要怎么做
  • 链表分割-双哨兵位
  • Python 查看各个库的版本
  • DotNet5在Docker中连接SqlServer2012,报错最大池超出
  • 【数据迁移】- Oracle GoldenGate(OGG)
  • 设计模式中的关联和依赖区别
  • ASP.NET Core 外部向SignalR的Hub发消息
  • MT6835 21位 磁编码器 SPI 平台无关通用驱动框架 STM32
  • 3.4 学习UVM中的uvm_monitor类分为几步?
  • 【论文笔记】Are Self-Attentions Effective for Time Series Forecasting? (NeurIPS 2024)
  • 移植BOA服务器到GEC2440开发板
  • 图解72个机器学习基础知识点
  • Flink怎么保证Exactly - Once 语义
  • 大型语言模型(LLM)中的自适应推理预算管理:基于约束策略优化的解决方案
  • 人工智能与低代码如何重新定义企业数字化转型?
  • Windows11系统笔记本电脑真的关机了么