spring源码分析——aop切面顺序实现原理

使用spring版本为4.3.22

1. 简介

对于同一个目标方法而言,切面触发的顺序如下:

Around->Before->businessFun->Around后续->After->AfterReturing/AfterThrowing

aspect.jpg

下边通过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 &lt; 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的顺序进行排序,如果注解相同,根据切面方法的方法名(包含包名和类名的完整名称),使用StringcompareTo()方法进行对比,简单说是根据字母序和字母长度进行排序,完成后,所有的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
		}
	}

AspectJAwareAdvisorAutoProxyCreator.png

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,所以上边逻辑中只要leastWithNoSmallersnull,那么才会触发赋值。

		@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.png

这个是AnnotationAwareOrderComparator的关联关系,实际上的调用的OrderComparatordoCompare方法,如下:

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;
	}

BeanFactoryAspectInstanaceFactory.png

通过上边的分析,就可以了解最终是如何调用到切面类的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属性的值,做一次排序,这次排序不会更改之前同一个类型中切面方法的相对顺序
  • 根据上边几步的排序结果,依次触发切面的逻辑

猜你喜欢

转载自blog.csdn.net/stpice/article/details/102628624
今日推荐