您的位置:首页 > 新闻 > 会展 > 公交建设公司官网_小程序定制服务_武汉seo排名优化公司_百度推广图片

公交建设公司官网_小程序定制服务_武汉seo排名优化公司_百度推广图片

2025/2/25 2:06:47 来源:https://blog.csdn.net/zlk252620068/article/details/145572428  浏览:    关键词:公交建设公司官网_小程序定制服务_武汉seo排名优化公司_百度推广图片
公交建设公司官网_小程序定制服务_武汉seo排名优化公司_百度推广图片

在 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) {// 默认的优先级比较器 AspectJPrecedenceComparatorpartiallyComparableAdvisors.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 sortingif (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;}}}// 不存在最小的,返回 nullif (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,将之前添加的作为 otherSortObject<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;// 利用默认的优先级比较器比较两个 advisorreturn 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.INSTANCEint 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 < o2if (p1 && !p2) {return -1;}// o2 PriorityOrdered,o1 非 PriorityOrdered// 返回 1,即 o1 > o2else if (p2 && !p1) {return 1;}// sourceProvider nullint 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;}// 注解中获取 orderreturn 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() {// 获取 orderif (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-1int 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 precedencereturn 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 precedencereturn 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 注解模式下创建的 Advisorif (anAdvisor instanceof AspectJPrecedenceInformation) {return (AspectJPrecedenceInformation) anAdvisor;}// AspectJPointcutAdvisor 获取持有 AdviceAdvice 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 里面移除 oother.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 网如下:

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com