使用spring版本为4.3.22
1. 简介
对于同一个目标方法而言,切面触发的顺序如下:
Around->Before->businessFun->Around后续->After->AfterReturing/AfterThrowing
。
下边通过spring源码分析一下,对于切面类和方法的执行顺序,spring是如何控制的。
2. spring上下文初始化的时候,第一次创建advisors的缓存时,对切面方法的排序过程
定位到目标类AnnotationAwareAspectJAutoProxyCreator
,通过90行的断点,进一步说明。具体的调用栈情况如下:
findCandidateAdvisors:90, AnnotationAwareAspectJAutoProxyCreator (org.springframework.aop.aspectj.annotation)
shouldSkip:103, AspectJAwareAdvisorAutoProxyCreator (org.springframework.aop.aspectj.autoproxy)
postProcessBeforeInstantiation:248, AbstractAutoProxyCreator (org.springframework.aop.framework.autoproxy)
applyBeanPostProcessorsBeforeInstantiation:1042, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
resolveBeforeInstantiation:1016, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
createBean:471, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
getObject:312, AbstractBeanFactory$1 (org.springframework.beans.factory.support)
getSingleton:230, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support)
doGetBean:308, AbstractBeanFactory (org.springframework.beans.factory.support)
getBean:197, AbstractBeanFactory (org.springframework.beans.factory.support)
preInstantiateSingletons:761, DefaultListableBeanFactory (org.springframework.beans.factory.support)
finishBeanFactoryInitialization:867, AbstractApplicationContext (org.springframework.context.support)
refresh:543, AbstractApplicationContext (org.springframework.context.support)
<init>:139, ClassPathXmlApplicationContext (org.springframework.context.support)
<init>:83, ClassPathXmlApplicationContext (org.springframework.context.support)
main:28, TestOrder (com.stpice.spring.demo.aop.order)
@Override
protected List<Advisor> findCandidateAdvisors() {
// Add all the Spring advisors found according to superclass rules.
List<Advisor> advisors = super.findCandidateAdvisors();
// Build Advisors for all AspectJ aspects in the bean factory.
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());//这里会构建所有的advisors,并添加到list里面
return advisors;
}
进入this.aspectJAdvisorsBuilder.buildAspectJAdvisors()
方法。
buildAspectJAdvisors:85, BeanFactoryAspectJAdvisorsBuilder (org.springframework.aop.aspectj.annotation)
findCandidateAdvisors:90, AnnotationAwareAspectJAutoProxyCreator (org.springframework.aop.aspectj.annotation)
...
类BeanFactoryAspectJAdvisorsBuilder
中的buildAspectJAdvisors
方法是真正的构建advisors的方法。这个方法比较长,这里针对其中比较关键的部分代码进行注释说明。
/**
* Look for AspectJ-annotated aspect beans in the current bean factory,
* and return to a list of Spring AOP Advisors representing them.
* <p>Creates a Spring Advisor for each AspectJ advice method.
* @return the list of {@link org.springframework.aop.Advisor} beans
* @see #isEligibleBean
*/
public List<Advisor> buildAspectJAdvisors() {
List<String> aspectNames = this.aspectBeanNames;//因为是单例的,初始的时候,切面bean的名字为null
if (aspectNames == null) {
//第一次为null的时候,会进入这个分支构建切面bean
synchronized (this) {
//以单例为锁进行同步
aspectNames = this.aspectBeanNames;//重新获取,防止并发时,其他线程已经进行过初始化
if (aspectNames == null) {
//尚未初始化
List<Advisor> advisors = new LinkedList<Advisor>();//先构造一个空的链表
aspectNames = new LinkedList<String>();//aspectNames是一个存放切面名字的临时列表
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);//从bean工厂中获取所有的bean名称
for (String beanName : beanNames) {
if (!isEligibleBean(beanName)) {
//遍历判断是否该bean的类型是否合适自动代理,这里会调用BeanFactoryAspectJAdvisorsBuilder子类AnnotationAwareAspectJAutoProxyCreator中的isEligibleBean方法,如果不满足,则继续遍历
continue;
}
// We must be careful not to instantiate beans eagerly as in this case they
// would be cached by the Spring container but would not have been weaved.
Class<?> beanType = this.beanFactory.getType(beanName);
if (beanType == null) {
continue;
}
if (this.advisorFactory.isAspect(beanType)) {
//满足则判断类型是否为切面
aspectNames.add(beanName);
AspectMetadata amd = new AspectMetadata(beanType, beanName);
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
//单例的处理方式
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);//从factory中获取advisors,这里涉及到初始获取各个切面实例中的切面方法时,每个方法的排列顺序,后边会具体进行分析
if (this.beanFactory.isSingleton(beanName)) {
this.advisorsCache.put(beanName, classAdvisors);//缓存单例的切面实例
}
else {
this.aspectFactoryCache.put(beanName, factory);//多例对切面工厂进行缓存
}
advisors.addAll(classAdvisors);//添加到advisors列表中
}
else {
// Per target or per this.
if (this.beanFactory.isSingleton(beanName)) {
throw new IllegalArgumentException("Bean with name '" + beanName +
"' is a singleton, but aspect instantiation model is not singleton");
}
MetadataAwareAspectInstanceFactory factory =
new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
this.aspectFactoryCache.put(beanName, factory);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
}
this.aspectBeanNames = aspectNames;//将名字保存到域变量中
return advisors;//初始化完成直接返回
}
}
}
if (aspectNames.isEmpty()) {
return Collections.emptyList();
}
List<Advisor> advisors = new LinkedList<Advisor>();
for (String aspectName : aspectNames) {
List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
if (cachedAdvisors != null) {
advisors.addAll(cachedAdvisors);
}
else {
MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
return advisors;
}
在ReflectiveAspectJAdvisorFactory
类中,会处理所有的advisors中的各个方法,并对方法进行排序包装。
getAdvisors:135, ReflectiveAspectJAdvisorFactory (org.springframework.aop.aspectj.annotation)
buildAspectJAdvisors:109, BeanFactoryAspectJAdvisorsBuilder (org.springframework.aop.aspectj.annotation)
findCandidateAdvisors:90, AnnotationAwareAspectJAutoProxyCreator (org.springframework.aop.aspectj.annotation)
...
@Override
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
validate(aspectClass);
// We need to wrap the MetadataAwareAspectInstanceFactory with a decorator
// so that it will only instantiate once.
MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
List<Advisor> advisors = new ArrayList<Advisor>();
for (Method method : getAdvisorMethods(aspectClass)) {
//这里获取所有advisors方法的时候,会对切面方法进行比较并排序
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);//包装advisor,并且将不是advisor的方法过滤掉
if (advisor != null) {
advisors.add(advisor);//加入列表
}
}
// If it's a per target aspect, emit the dummy instantiating aspect.
if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
advisors.add(0, instantiationAdvisor);
}
// Find introduction fields.
for (Field field : aspectClass.getDeclaredFields()) {
Advisor advisor = getDeclareParentsAdvisor(field);
if (advisor != null) {
advisors.add(advisor);
}
}
return advisors;
}
getAdvisorMethods:160, ReflectiveAspectJAdvisorFactory (org.springframework.aop.aspectj.annotation)
getAdvisors:135, ReflectiveAspectJAdvisorFactory (org.springframework.aop.aspectj.annotation)
buildAspectJAdvisors:109, BeanFactoryAspectJAdvisorsBuilder (org.springframework.aop.aspectj.annotation)
findCandidateAdvisors:90, AnnotationAwareAspectJAutoProxyCreator (org.springframework.aop.aspectj.annotation)
...
private List<Method> getAdvisorMethods(Class<?> aspectClass) {
final List<Method> methods = new ArrayList<Method>();
ReflectionUtils.doWithMethods(aspectClass, new ReflectionUtils.MethodCallback() {
@Override
public void doWith(Method method) throws IllegalArgumentException {
// Exclude pointcuts 这里跳过了切点注解的方法
if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) {
methods.add(method);
}
}
});
Collections.sort(methods, METHOD_COMPARATOR);//对所有的advisors方法进行排序,使用的METHOD_COMPARATOR,放在类静态代码块中,下边会说明
return methods;
}
上述代码中的methods
,包含了该切面对象的所有方法, 包括父类的方法等,如下:
0 = {
Method@1880} "public void com.stpice.spring.demo.aop.order.AspectJOrderHigh.beforeTest()"
1 = {
Method@1881} "public void com.stpice.spring.demo.aop.order.AspectJOrderHigh.afterTest()"
2 = {
Method@1882} "public java.lang.Object com.stpice.spring.demo.aop.order.AspectJOrderHigh.aroundTest(org.aspectj.lang.ProceedingJoinPoint) throws java.lang.Throwable"
3 = {
Method@1883} "public int com.stpice.spring.demo.aop.order.AspectJOrderHigh.getOrder()"
4 = {
Method@1884} "protected void java.lang.Object.finalize() throws java.lang.Throwable"
5 = {
Method@1885} "public final void java.lang.Object.wait() throws java.lang.InterruptedException"
6 = {
Method@1886} "public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException"
7 = {
Method@1887} "public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException"
8 = {
Method@1888} "public boolean java.lang.Object.equals(java.lang.Object)"
9 = {
Method@1889} "public java.lang.String java.lang.Object.toString()"
10 = {
Method@1890} "public native int java.lang.Object.hashCode()"
11 = {
Method@1891} "public final native java.lang.Class java.lang.Object.getClass()"
12 = {
Method@1892} "protected native java.lang.Object java.lang.Object.clone() throws java.lang.CloneNotSupportedException"
13 = {
Method@1893} "public final native void java.lang.Object.notify()"
14 = {
Method@1894} "public final native void java.lang.Object.notifyAll()"
15 = {
Method@1895} "private static native void java.lang.Object.registerNatives()"
在类ReflectiveAspectJAdvisorFactory
初始化的时候,会实例化METHOD_COMPARATOR
,保存好。

private static final Comparator<Method> METHOD_COMPARATOR;
static {
//注册两个比较器,先根据下边声明的注解类顺序,进行比对,如果注解相同的话,再把目标方法转换为String,调用String的compareTo()方法进行比较
CompoundComparator<Method> comparator = new CompoundComparator<Method>();
comparator.addComparator(new ConvertingComparator<Method, Annotation>(//将方法转换为注解,然后进行注解对比
new InstanceComparator<Annotation>(
Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class),//实例比较器,按照上边切面类的顺序,对切面方法注解进行判断比较
new Converter<Method, Annotation>() {
@Override
public Annotation convert(Method method) {
AspectJAnnotation<?> annotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(method);
return (annotation != null ? annotation.getAnnotation() : null);
}//转换器会将比较的目标对象转换为切面方法的注解返回
}));
comparator.addComparator(new ConvertingComparator<Method, String>(//将方法转换为String,然后进行对比
new Converter<Method, String>() {
@Override
public String convert(Method method) {
return method.getName();//转换器会将目标对象的转换为String再进行比对
}
}));
METHOD_COMPARATOR = comparator;
}
在compare
方法中会遍历两个Comparator,然后分别进行比较。
compare:173, CompoundComparator (org.springframework.util.comparator)
countRunAndMakeAscending:355, TimSort (java.util)
sort:220, TimSort (java.util)
sort:1512, Arrays (java.util)
sort:1460, ArrayList (java.util)
sort:175, Collections (java.util)
getAdvisorMethods:170, ReflectiveAspectJAdvisorFactory (org.springframework.aop.aspectj.annotation)
getAdvisors:135, ReflectiveAspectJAdvisorFactory (org.springframework.aop.aspectj.annotation)
buildAspectJAdvisors:109, BeanFactoryAspectJAdvisorsBuilder (org.springframework.aop.aspectj.annotation)
findCandidateAdvisors:90, AnnotationAwareAspectJAutoProxyCreator (org.springframework.aop.aspectj.annotation)
...
public int compare(T o1, T o2) {
Assert.state(this.comparators.size() > 0,
"No sort definitions have been added to this CompoundComparator to compare");
for (InvertibleComparator comparator : this.comparators) {
int result = comparator.compare(o1, o2);
if (result != 0) {
return result;
}
}
return 0;
}
compare:56, InstanceComparator (org.springframework.util.comparator)
compare:81, ConvertingComparator (org.springframework.core.convert.converter)
compare:89, InvertibleComparator (org.springframework.util.comparator)
compare:174, CompoundComparator (org.springframework.util.comparator)
countRunAndMakeAscending:355, TimSort (java.util)
sort:220, TimSort (java.util)
sort:1512, Arrays (java.util)
sort:1460, ArrayList (java.util)
sort:175, Collections (java.util)
getAdvisorMethods:170, ReflectiveAspectJAdvisorFactory (org.springframework.aop.aspectj.annotation)
getAdvisors:135, ReflectiveAspectJAdvisorFactory (org.springframework.aop.aspectj.annotation)
buildAspectJAdvisors:109, BeanFactoryAspectJAdvisorsBuilder (org.springframework.aop.aspectj.annotation)
findCandidateAdvisors:90, AnnotationAwareAspectJAutoProxyCreator (org.springframework.aop.aspectj.annotation)
...
@Override
public int compare(T o1, T o2) {
int i1 = getOrder(o1);//通过调用getOrder获取顺序
int i2 = getOrder(o2);
return (i1 < i2 ? -1 : (i1 == i2 ? 0 : 1));//<,=,>分别返回-1,0,1
}
private int getOrder(T object) {
if (object != null) {
for (int i = 0; i < this.instanceOrder.length; i++) {
if (this.instanceOrder[i].isInstance(object)) {
//看命中列表中的第几个,表示顺序是多少,通过顺序号进行对比
return i;
}
}
}
return this.instanceOrder.length;
}
0 = {
Class@1755} "interface org.aspectj.lang.annotation.Around"
1 = {
Class@1751} "interface org.aspectj.lang.annotation.Before"
2 = {
Class@1753} "interface org.aspectj.lang.annotation.After"
3 = {
Class@2064} "interface org.aspectj.lang.annotation.AfterReturning"
4 = {
Class@2065} "interface org.aspectj.lang.annotation.AfterThrowing"
上边即时上文中提供的切面方法的顺序,根据这个顺序进行对比。
另外,如果两个方法上的注解相同,那么会触发第二个比较器,String
的比较器,如下:
/**
* Compares two strings lexicographically.
* The comparison is based on the Unicode value of each character in
* the strings. The character sequence represented by this
* {@code String} object is compared lexicographically to the
* character sequence represented by the argument string. The result is
* a negative integer if this {@code String} object
* lexicographically precedes the argument string. The result is a
* positive integer if this {@code String} object lexicographically
* follows the argument string. The result is zero if the strings
* are equal; {@code compareTo} returns {@code 0} exactly when
* the {@link #equals(Object)} method would return {@code true}.
* <p>
* This is the definition of lexicographic ordering. If two strings are
* different, then either they have different characters at some index
* that is a valid index for both strings, or their lengths are different,
* or both. If they have different characters at one or more index
* positions, let <i>k</i> be the smallest such index; then the string
* whose character at position <i>k</i> has the smaller value, as
* determined by using the < operator, lexicographically precedes the
* other string. In this case, {@code compareTo} returns the
* difference of the two character values at position {@code k} in
* the two string -- that is, the value:
* <blockquote><pre>
* this.charAt(k)-anotherString.charAt(k)
* </pre></blockquote>
* If there is no index position at which they differ, then the shorter
* string lexicographically precedes the longer string. In this case,
* {@code compareTo} returns the difference of the lengths of the
* strings -- that is, the value:
* <blockquote><pre>
* this.length()-anotherString.length()
* </pre></blockquote>
*
* @param anotherString the {@code String} to be compared.
* @return the value {@code 0} if the argument string is equal to
* this string; a value less than {@code 0} if this string
* is lexicographically less than the string argument; and a
* value greater than {@code 0} if this string is
* lexicographically greater than the string argument.
*/
public int compareTo(String anotherString) {
int len1 = value.length;
int len2 = anotherString.value.length;
int lim = Math.min(len1, len2);
char v1[] = value;
char v2[] = anotherString.value;
int k = 0;
while (k < lim) {
char c1 = v1[k];
char c2 = v2[k];
if (c1 != c2) {
return c1 - c2;
}
k++;
}
return len1 - len2;
}
注释已经解释的很详细了,这里大致描述一下,两个字符串比较,只比较二者较短的字母长度
,如果遇到当前实例的字符串大,返回正数,如果小,返回负数,如果等,继续向下比较,如果可比较的长度内完全相同,那么长度较短的小。大致是这么个比较过程,总结一下,大致就是字母序比较,如果前N个字符相同,
getAdvisor:205, ReflectiveAspectJAdvisorFactory (org.springframework.aop.aspectj.annotation)
getAdvisors:136, ReflectiveAspectJAdvisorFactory (org.springframework.aop.aspectj.annotation)
buildAspectJAdvisors:109, BeanFactoryAspectJAdvisorsBuilder (org.springframework.aop.aspectj.annotation)
findCandidateAdvisors:90, AnnotationAwareAspectJAutoProxyCreator (org.springframework.aop.aspectj.annotation)
...
@Override
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
int declarationOrderInAspect, String aspectName) {
validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
AspectJExpressionPointcut expressionPointcut = getPointcut(
candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());//获取方法对应的切面,如果为null,则不是切面方法,跳过该条
if (expressionPointcut == null) {
return null;
}
return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
this, aspectInstanceFactory, declarationOrderInAspect, aspectName);//包装切面方法
}
通过上文描述,advisors的初始化工作已经完成了。总结一下,对应不同的advisors实例,只是添加到了列表中,并且在BeanFactoryAspectJAdvisorsBuilder
的域变量中做了缓存,尚未排序,只是对同一个类型的实例中不同的切面方法进行了排序,排序使用了两个比较器,首先是扫描方法注解,根据Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class
的顺序进行排序,如果注解相同,根据切面方法的方法名(包含包名和类名的完整名称),使用String
的compareTo()
方法进行对比,简单说是根据字母序和字母长度进行排序,完成后,所有的advisor方法会按照其属于不同的切面类,以beanName
作为key,保存到缓存中,以备后续触发切面逻辑时进行使用。
2. 在每次触发切面方法的时候,进行匹配的方法筛选,并对切面类进行排序
在调用切面目标方法的时候,会进入AbstractAdvisorAutoProxyCreator
方法中的findEligibleAdvisors
函数,并且随后会再次进入BeanFactoryAspectJAdvisorsBuilder
中的buildAspectJAdvisors
,具体如下两部分代码。
findEligibleAdvisors:88, AbstractAdvisorAutoProxyCreator (org.springframework.aop.framework.autoproxy)
getAdvicesAndAdvisorsForBean:70, AbstractAdvisorAutoProxyCreator (org.springframework.aop.framework.autoproxy)
wrapIfNecessary:346, AbstractAutoProxyCreator (org.springframework.aop.framework.autoproxy)
postProcessAfterInitialization:298, AbstractAutoProxyCreator (org.springframework.aop.framework.autoproxy)
applyBeanPostProcessorsAfterInitialization:421, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
initializeBean:1635, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
doCreateBean:553, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
createBean:481, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
getObject:312, AbstractBeanFactory$1 (org.springframework.beans.factory.support)
getSingleton:230, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support)
doGetBean:308, AbstractBeanFactory (org.springframework.beans.factory.support)
getBean:197, AbstractBeanFactory (org.springframework.beans.factory.support)
preInstantiateSingletons:761, DefaultListableBeanFactory (org.springframework.beans.factory.support)
finishBeanFactoryInitialization:867, AbstractApplicationContext (org.springframework.context.support)
refresh:543, AbstractApplicationContext (org.springframework.context.support)
<init>:139, ClassPathXmlApplicationContext (org.springframework.context.support)
<init>:83, ClassPathXmlApplicationContext (org.springframework.context.support)
main:28, TestOrder (com.stpice.spring.demo.aop.order)
/**
* Find all eligible Advisors for auto-proxying this class.
* @param beanClass the clazz to find advisors for
* @param beanName the name of the currently proxied bean
* @return the empty List, not {@code null},
* if there are no pointcuts or interceptors
* @see #findCandidateAdvisors
* @see #sortAdvisors
* @see #extendAdvisors
*/
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
List<Advisor> candidateAdvisors = findCandidateAdvisors();//查到到候补的advisors,这个查出来的是所有的advisors,后边会具体说明
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);//找到合适的advisors,这是针对candidateAdvisors,根据特定的bean类型和名称过滤
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);//对筛选出的advisors进行排序
}
return eligibleAdvisors;
}
buildAspectJAdvisors:85, BeanFactoryAspectJAdvisorsBuilder (org.springframework.aop.aspectj.annotation)
findCandidateAdvisors:90, AnnotationAwareAspectJAutoProxyCreator (org.springframework.aop.aspectj.annotation)
findEligibleAdvisors:88, AbstractAdvisorAutoProxyCreator (org.springframework.aop.framework.autoproxy)
...
/**
* Look for AspectJ-annotated aspect beans in the current bean factory,
* and return to a list of Spring AOP Advisors representing them.
* <p>Creates a Spring Advisor for each AspectJ advice method.
* @return the list of {@link org.springframework.aop.Advisor} beans
* @see #isEligibleBean
*/
public List<Advisor> buildAspectJAdvisors() {
List<String> aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
//再次进入这个方法的时候,由于该实例中的aspectBeanNames已经在初始化的时候进行赋值,所以aspectNames不为null,不会进入这个分支。简单来说,就是这里只有在初始化时候进入一次
synchronized (this) {
aspectNames = this.aspectBeanNames;
/**
* Look for AspectJ-annotated aspect beans in the current bean factory,
* and return to a list of Spring AOP Advisors representing them.
* <p>Creates a Spring Advisor for each AspectJ advice method.
* @return the list of {@link org.springframework.aop.Advisor} beans
* @see #isEligibleBean
*/
public List<Advisor> buildAspectJAdvisors() {
List<String> aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
...}
if (aspectNames.isEmpty()) {
//如果没有缓存切面类的名称,则没有切面,返回空集合
return Collections.emptyList();
}
List<Advisor> advisors = new LinkedList<Advisor>();
for (String aspectName : aspectNames) {
List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);//如果有切面类,则从缓存中,按照对应的切面名称取出实际的advisors,然后添加到上边实例化的Advisor链表中
if (cachedAdvisors != null) {
advisors.addAll(cachedAdvisors);
}
else {
MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);//这里对应非单例模式的切面,从切面工厂缓存中获取到切面工厂类
advisors.addAll(this.advisorFactory.getAdvisors(factory));//通过调用getAdvisors方法,产生advisors,加入列表
}
}
return advisors;
}
上边代码中对应的advisor
,都是一个对应到具体的切面方法的。
获取到advisors的列表后,返回之前调用的findEligibleAdivsors
方法,继续调用sortAdvisors
对各个切面方法进行排序,这里的排序不会打乱每个匹配的切面类中各个切面方法的顺序,只会根据切面类的Order
对各个类进行排序,由于现在的列表中都是对应切面方法,而Advisor
这个对象中包含了它所在的切面类是哪个。下边会对应进入sortAdvisors
方法看对切面类排序的过程。
findEligibleAdvisors:92, AbstractAdvisorAutoProxyCreator (org.springframework.aop.framework.autoproxy)
...
/**
* Find all eligible Advisors for auto-proxying this class.
* @param beanClass the clazz to find advisors for
* @param beanName the name of the currently proxied bean
* @return the empty List, not {@code null},
* if there are no pointcuts or interceptors
* @see #findCandidateAdvisors
* @see #sortAdvisors
* @see #extendAdvisors
*/
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);//对切面类通过order进行排序,不会改变每个切面类中对应的切面方法的顺序
}
return eligibleAdvisors;
}
sortAdvisors:70, AspectJAwareAdvisorAutoProxyCreator (org.springframework.aop.aspectj.autoproxy)
findEligibleAdvisors:92, AbstractAdvisorAutoProxyCreator (org.springframework.aop.framework.autoproxy)
...
protected List<Advisor> sortAdvisors(List<Advisor> advisors) {
List<PartiallyComparableAdvisorHolder> partiallyComparableAdvisors =
new ArrayList<PartiallyComparableAdvisorHolder>(advisors.size());//先根据切面列表中切面的个数,创建一个用于比较切面的Holder类列表,这里名字为“部分比较”,个人猜测是只做了类order的比较
for (Advisor element : advisors) {
partiallyComparableAdvisors.add(
new PartiallyComparableAdvisorHolder(element, DEFAULT_PRECEDENCE_COMPARATOR));//将原始的advisor类进行包装,放入列表中,这里用到的比较器是DEFAULT_PRECEDENCE_COMPARATOR,默认的一个比较器,下边会对这个比较器进行具体分析
}
List<PartiallyComparableAdvisorHolder> sorted =
PartialOrder.sort(partiallyComparableAdvisors);//实际的排序函数,这个PartialOrder方法是aspectj包提供的一个排序方法,简单来说,内部使用了简单排序中的选择排序,后边会具体后说明
if (sorted != null) {
//排序后,再从包装类中将advisor取出来,重新放回列表中返回
List<Advisor> result = new ArrayList<Advisor>(advisors.size());
for (PartiallyComparableAdvisorHolder pcAdvisor : sorted) {
result.add(pcAdvisor.getAdvisor());
}
return result;
}
else {
return super.sortAdvisors(advisors);//如果PartialOrder比较方法返回结果为null,则使用父类AbstractAdvisorAutoProxyCreator的排序方法,AnnotationAwareOrderComparator.sort(advisors);146
}
}
AspectJPrecedenceComparator
的构造函数中,创建了一个AnnotationAwareOrderComparator
比较器的实例,其中关键处在于获取order的方法,即findOrder
,如下AnnotationAwareOrderComparator
类中代码:
/**
* This implementation checks for {@link Order @Order} or
* {@link javax.annotation.Priority @Priority} on various kinds of
* elements, in addition to the {@link org.springframework.core.Ordered}
* check in the superclass.
*/
@Override
protected Integer findOrder(Object obj) {
// Check for regular Ordered interface
Integer order = super.findOrder(obj);//调用父类方法,获取实现了Ordered接口的实例的order值,这里比较时使用的获取order就是调用这个方法,后文会继续说明
if (order != null) {
return order;
}
// Check for @Order and @Priority on various kinds of elements
if (obj instanceof Class) {
//如果是class,通过OrderUtils获取order属性值
return OrderUtils.getOrder((Class<?>) obj);//这里面会获取类上@Order的注解的值
}
else if (obj instanceof Method) {
Order ann = AnnotationUtils.findAnnotation((Method) obj, Order.class);//如果目标是方法,从方法上获取@Order注解
if (ann != null) {
return ann.value();
}
}
else if (obj instanceof AnnotatedElement) {
Order ann = AnnotationUtils.getAnnotation((AnnotatedElement) obj, Order.class);
if (ann != null) {
return ann.value();
}
}
else if (obj != null) {
order = OrderUtils.getOrder(obj.getClass());
if (order == null && obj instanceof DecoratingProxy) {
order = OrderUtils.getOrder(((DecoratingProxy) obj).getDecoratedClass());
}
}
return order;
}
上边这个比较,在上文中的父类比较器,也是同一个,都会触发这个逻辑,获取order
属性,然后对order属性进行比较后排序。
/**
* Sort the given List with a default AnnotationAwareOrderComparator.
* <p>Optimized to skip sorting for lists with size 0 or 1,
* in order to avoid unnecessary array extraction.
* @param list the List to sort
* @see java.util.Collections#sort(java.util.List, java.util.Comparator)
*/
public static void sort(List<?> list) {
if (list.size() > 1) {
Collections.sort(list, INSTANCE);//排序使用的Collections的sort方法,实例即为上文提到的AnnotationAwareOrderComparator实例
}
}
3. 下边说明具体的排序方法
List<PartiallyComparableAdvisorHolder> sorted = PartialOrder.sort(partiallyComparableAdvisors);
主要是这一行代码,进入代码发现时aspectjweaver
包中的实现的一个排序方法。下边这段代码,是在实际触发切面目标的业务方法时候,每次都会执行的,会对筛选出来符合目标业务方法的切面,做一次排序,所有的实现都在这个PartialOrder.sort()
方法中。具体如下:
sort:119, PartialOrder (org.aspectj.util)
sortAdvisors:77, AspectJAwareAdvisorAutoProxyCreator (org.springframework.aop.aspectj.autoproxy)
findEligibleAdvisors:92, AbstractAdvisorAutoProxyCreator (org.springframework.aop.framework.autoproxy)
getAdvicesAndAdvisorsForBean:70, AbstractAdvisorAutoProxyCreator (org.springframework.aop.framework.autoproxy)
...
/**
* @param objects must all implement PartialComparable
*
* @returns the same members as objects, but sorted according to their partial order. returns null if the objects are cyclical
*
*/
public static List sort(List 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.
// 这里上边解释了半天,是他不想构造这个数据结构,但是又觉得这个数据结构可以分离很多复杂的逻辑
// 下边这个方法是构造了一个SortObject,将advisors列表中每个元素,都用SortObject包装一下,包装后,里面会保存比当前这个advisor大的元素有几个,小的有几个,这样两个列表,后边的逻辑中会根据这两个列表中的值,进行具体的排序比较
List<SortObject> sortList = new LinkedList<SortObject>(); // objects.size());
for (Iterator i = objects.iterator(); i.hasNext();) {
addNewPartialComparable(sortList, (PartialComparable) i.next());//将advisor包装成SortObject,并加入sortList
}
// 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++) {
//下边会进行两次嵌套的遍历,从sortList中选出最小的,放入objects中
// System.out.println(sortList);
// System.out.println("-->" + ret);
SortObject leastWithNoSmallers = null;
for (Iterator i = sortList.iterator(); i.hasNext();) {
SortObject so = (SortObject) i.next();
// System.out.println(so);
if (so.hasNoSmallerObjects()) {
//判断有无更小的对象,如果没有,则当前的对象为最小
if (leastWithNoSmallers == null || so.object.fallbackCompareTo(leastWithNoSmallers.object) < 0) {
//fallbackCompareTo总会返回0
leastWithNoSmallers = so;
}
}
}
if (leastWithNoSmallers == null) {
return null;
}
removeFromGraph(sortList, leastWithNoSmallers);//从sortList中移除最小的对象,这个会遍历sortList中的所有对象,从各个对象保存比自己小的对象的列表中移除掉,后边会具体说
objects.set(index, leastWithNoSmallers.object);//从SortObject中取出advisor,放入objects列表中
}
return objects;
}
private static void addNewPartialComparable(List<SortObject> graph, PartialComparable o) {
SortObject so = new SortObject(o);
for (Iterator<SortObject> i = graph.iterator(); i.hasNext();) {
SortObject other = i.next();
so.addDirectedLinks(other);//遍历现有的graph列表,将新元素与老元素进行对比并添加关联关系,后文具体说明
}
graph.add(so);
}
AspectJAwareAdvisorAutoProxyCreator
中的fallbackCompareTo
总会返回0,所以上边逻辑中只要leastWithNoSmallers
为null
,那么才会触发赋值。
@Override
public int fallbackCompareTo(Object obj) {
return 0;
}
PartialOrder
中的这个方法,会遍历删除所有对象,从smallerObjects
中删除o
。
private static void removeFromGraph(List<SortObject> graph, SortObject o) {
for (Iterator<SortObject> i = graph.iterator(); i.hasNext();) {
SortObject other = i.next();
if (o == other) {
i.remove();//删除graph中的对象o
}
// ??? could use this to build up a new queue of objects with no
// ??? smaller ones
other.removeSmallerObject(o);//删除graph其他对象中的smallerObjects中的o
}
}
PartialOrder
中的SortObject
对象如下:
private static class SortObject {
PartialComparable object;
List<SortObject> smallerObjects = new LinkedList<SortObject>();//保存比自己小的对象列表
List<SortObject> biggerObjects = new LinkedList<SortObject>();//保存比自己大的对象列表
public SortObject(PartialComparable o) {
object = o;
}
boolean hasNoSmallerObjects() {
return smallerObjects.size() == 0;
}
boolean removeSmallerObject(SortObject o) {
smallerObjects.remove(o);
return hasNoSmallerObjects();
}
void addDirectedLinks(SortObject other) {
//这里是上文提到的添加大小关联关系的方法
int cmp = object.compareTo(other.object);//先做比较,这里的object里面的比较器是AspectJPrecedenceComparator,上文提到过
if (cmp == 0) {
return;
}
if (cmp > 0) {
//根据大小,会在两个对象中的smallerObjects、biggerObjects中分别加入对应的关联关系
this.smallerObjects.add(other);
other.biggerObjects.add(this);
} else {
this.biggerObjects.add(other);
other.smallerObjects.add(this);
}
}
public String toString() {
return object.toString(); // +smallerObjects+biggerObjects;
}
}
int cmp = object.compareTo(other.object);
中的方法,具体如下:
@Override
public int compare(Advisor o1, Advisor o2) {
int advisorPrecedence = this.advisorComparator.compare(o1, o2);//比较o1,o2,这里的advisorComparator是AnnotationAwareOrderComparator的一个实例
if (advisorPrecedence == SAME_PRECEDENCE && declaredInSameAspect(o1, o2)) {
advisorPrecedence = comparePrecedenceWithinAspect(o1, o2);
}
return advisorPrecedence;
}
这个是AnnotationAwareOrderComparator
的关联关系,实际上的调用的OrderComparator
的doCompare
方法,如下:
doCompare:77, OrderComparator (org.springframework.core)
compare:73, OrderComparator (org.springframework.core)
compare:81, AspectJPrecedenceComparator (org.springframework.aop.aspectj.autoproxy)
compare:49, AspectJPrecedenceComparator (org.springframework.aop.aspectj.autoproxy)
compareTo:132, AspectJAwareAdvisorAutoProxyCreator$PartiallyComparableAdvisorHolder (org.springframework.aop.aspectj.autoproxy)
addDirectedLinks:71, PartialOrder$SortObject (org.aspectj.util)
addNewPartialComparable:93, PartialOrder (org.aspectj.util)
sort:129, PartialOrder (org.aspectj.util)
sortAdvisors:77, AspectJAwareAdvisorAutoProxyCreator (org.springframework.aop.aspectj.autoproxy)
findEligibleAdvisors:92, AbstractAdvisorAutoProxyCreator (org.springframework.aop.framework.autoproxy)
getAdvicesAndAdvisorsForBean:70, AbstractAdvisorAutoProxyCreator (org.springframework.aop.framework.autoproxy)
...
private int doCompare(Object o1, Object o2, OrderSourceProvider sourceProvider) {
boolean p1 = (o1 instanceof PriorityOrdered);//会优先判断是否是PriorityOrdered接口的实现
boolean p2 = (o2 instanceof PriorityOrdered);
if (p1 && !p2) {
return -1;
}
else if (p2 && !p1) {
return 1;
}
// Direct evaluation instead of Integer.compareTo to avoid unnecessary object creation.
int i1 = getOrder(o1, sourceProvider);//调用获取order属性值
int i2 = getOrder(o2, sourceProvider);
return (i1 < i2) ? -1 : (i1 > i2) ? 1 : 0;
}
getOrder:100, OrderComparator (org.springframework.core)
doCompare:87, OrderComparator (org.springframework.core)
compare:73, OrderComparator (org.springframework.core)
compare:81, AspectJPrecedenceComparator (org.springframework.aop.aspectj.autoproxy)
compare:49, AspectJPrecedenceComparator (org.springframework.aop.aspectj.autoproxy)
compareTo:132, AspectJAwareAdvisorAutoProxyCreator$PartiallyComparableAdvisorHolder (org.springframework.aop.aspectj.autoproxy)
addDirectedLinks:71, PartialOrder$SortObject (org.aspectj.util)
addNewPartialComparable:93, PartialOrder (org.aspectj.util)
sort:129, PartialOrder (org.aspectj.util)
sortAdvisors:77, AspectJAwareAdvisorAutoProxyCreator (org.springframework.aop.aspectj.autoproxy)
findEligibleAdvisors:92, AbstractAdvisorAutoProxyCreator (org.springframework.aop.framework.autoproxy)
getAdvicesAndAdvisorsForBean:70, AbstractAdvisorAutoProxyCreator (org.springframework.aop.framework.autoproxy)
...
/**
* Determine the order value for the given object.
* <p>The default implementation checks against the given {@link OrderSourceProvider}
* using {@link #findOrder} and falls back to a regular {@link #getOrder(Object)} call.
* @param obj the object to check
* @return the order value, or {@code Ordered.LOWEST_PRECEDENCE} as fallback
*/
private int getOrder(Object obj, OrderSourceProvider sourceProvider) {
Integer order = null;
if (sourceProvider != null) {
Object orderSource = sourceProvider.getOrderSource(obj);
if (orderSource != null && orderSource.getClass().isArray()) {
Object[] sources = ObjectUtils.toObjectArray(orderSource);
for (Object source : sources) {
order = findOrder(source);
if (order != null) {
break;
}
}
}
else {
order = findOrder(orderSource);
}
}
return (order != null ? order : getOrder(obj));//没有配置provider,直接调用getOrder中的findeOrder方法,这个方法是在子类AnnotationAwareOrderComparator中实现的,在上文中已经分析过
}
getOrder:127, BeanFactoryAspectInstanceFactory (org.springframework.aop.aspectj.annotation)
getOrder:87, LazySingletonAspectInstanceFactoryDecorator (org.springframework.aop.aspectj.annotation)
getOrder:173, InstantiationModelAwarePointcutAdvisorImpl (org.springframework.aop.aspectj.annotation)
findOrder:139, OrderComparator (org.springframework.core)
findOrder:64, AnnotationAwareOrderComparator (org.springframework.core.annotation)
getOrder:127, OrderComparator (org.springframework.core)
getOrder:116, OrderComparator (org.springframework.core)
doCompare:87, OrderComparator (org.springframework.core)
compare:73, OrderComparator (org.springframework.core)
compare:81, AspectJPrecedenceComparator (org.springframework.aop.aspectj.autoproxy)
compare:49, AspectJPrecedenceComparator (org.springframework.aop.aspectj.autoproxy)
compareTo:132, AspectJAwareAdvisorAutoProxyCreator$PartiallyComparableAdvisorHolder (org.springframework.aop.aspectj.autoproxy)
addDirectedLinks:71, PartialOrder$SortObject (org.aspectj.util)
addNewPartialComparable:93, PartialOrder (org.aspectj.util)
sort:129, PartialOrder (org.aspectj.util)
sortAdvisors:77, AspectJAwareAdvisorAutoProxyCreator (org.springframework.aop.aspectj.autoproxy)
findEligibleAdvisors:92, AbstractAdvisorAutoProxyCreator (org.springframework.aop.framework.autoproxy)
getAdvicesAndAdvisorsForBean:70, AbstractAdvisorAutoProxyCreator (org.springframework.aop.framework.autoproxy)
...
/**
* Determine the order for this factory's target aspect, either
* an instance-specific order expressed through implementing the
* {@link org.springframework.core.Ordered} interface (only
* checked for singleton beans), or an order expressed through the
* {@link org.springframework.core.annotation.Order} annotation
* at the class level.
* @see org.springframework.core.Ordered
* @see org.springframework.core.annotation.Order
*/
@Override
public int getOrder() {
//这里会追溯到BeanFactoryAspectInstanaceFactory类中的方法
Class<?> type = this.beanFactory.getType(this.name);
if (type != null) {
if (Ordered.class.isAssignableFrom(type) && this.beanFactory.isSingleton(this.name)) {
//判断类型是否匹配,是否是单例
return ((Ordered) this.beanFactory.getBean(this.name)).getOrder();//会从beanFactory中获取到这个bean,然后调用bean里面的getOrder方法,获取order值
}
return OrderUtils.getOrder(type, Ordered.LOWEST_PRECEDENCE);//条件不匹配,即没有实现Ordered接口,或者不是单例,那么返回最低优先级,即Integer的最大值2147483647
}
return Ordered.LOWEST_PRECEDENCE;
}
通过上边的分析,就可以了解最终是如何调用到切面类的getOrder
方法,并根据order
的值进行排序的。
4. 入口方法简介
从main方法的代码跟踪进入,发现advisors的生成context初始化的时候只会做一次,然后就将所有的advisors保存在实例的域变量中的一个缓存中,后续都会从这个缓存中读取。
初始化会调用AbstractApplicationContext
中的refresh
方法,进一步调用finishBeanFactoryInitialization
方法进行单例的实例化。
refresh:543, AbstractApplicationContext (org.springframework.context.support)
<init>:139, ClassPathXmlApplicationContext (org.springframework.context.support)
<init>:83, ClassPathXmlApplicationContext (org.springframework.context.support)
main:28, TestOrder (com.stpice.spring.demo.aop.order)
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);//进行单例实例化,因为我配置的切面为单例
// Last step: publish corresponding event.
finishRefresh();
5. 总结
通过上文的分析,总结切面的顺序控制如下:
- 初始化时,将所有切面加载到一个域成员变量的
Map
缓存中,加载时会将每个切面类中的切面方法进行排序 - 切面方法中的排序方式,首先根据切面注解触发的顺序排序,然后根据字母序进行排序
- 初始化完成后,每个切面类中的切面方法的顺序就不会再次改变了
- 每次调用切面命中的业务代码时,会触发切面扫描,筛选出匹配的切面方法,根据切面方法所在的切面类,通过order属性的值,做一次排序,
这次排序不会更改之前同一个类型中切面方法的相对顺序
- 根据上边几步的排序结果,依次触发切面的逻辑