使用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